home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 010 / blit.arc / BITBLT.ASM < prev    next >
Encoding:
Assembly Source File  |  1985-08-02  |  104.6 KB  |  2,574 lines

  1.                .XLIST
  2.                PAGE   60,132
  3.          TITLE BITBLT-BIT BLOCK XFER FOR IBM PC  VERSION 1.0  BY T. PISEK---
  4.                .LIST
  5. BITBLT         PROC   FAR
  6. ?BITBLT        SEGMENT WORD PUBLIC 'CODE'
  7.                ASSUME  CS:?BITBLT,DS:?BITBLT
  8.                JMP      BITBLT_MAIN
  9. ;*********************************************************************
  10. ;                                                                    *
  11. ;                                                                    *
  12. ;                                                                    *
  13. ;                                                                    *
  14. ;                                                                    *
  15. ;                                                                    *
  16. ;                                                                    *
  17. ; BBBBBBB    IIIIIIII  TTTTTTTTTT  BBBBBBB    LL       TTTTTTTTTT    *
  18. ; B      B      II         TT      B      B   LL           TT        *
  19. ; B      B      II         TT      B      B   LL           TT        *
  20. ; BBBBBBB       II         TT      BBBBBBB    LL           TT        *
  21. ; B      B      II         TT      B      B   LL           TT        *
  22. ; B      B      II         TT      B      B   LL_____      TT        *
  23. ; BBBBBBB    IIIIIIII      TT      BBBBBBB    LLLLLLL      TT        *
  24. ;                                                                    *
  25. ;                                                                    *
  26. ;                                                                    *
  27. ;                                                                    *
  28. ;                                                                    *
  29. ;                                                                    *
  30. ;                                                                    *
  31. ;*********************************************************************
  32. ;
  33.                .XLIST
  34.                SUBTTL      BITBLT MODE OPERATION PARAMETERS
  35.                .LIST
  36.                PAGE +
  37. BITS_WORD      EQU    16          ;BITS PER WORD
  38. ;*********************************************************************
  39. ;                                                                    *
  40. ; THE FOLLOWING ARE SET ON INITALIZATION CALL TO BITBLT              *
  41. ;                                                                    *
  42. ;*********************************************************************
  43. ;
  44. PIXELS_WORD    DW      8          ;NUMBER OF PIXELS/WORD
  45. LOG_PIX_WRD    DW      3          ;LOG OF ABOVE
  46. BITS_PIXEL     DW      2          ;BITS PER PIXEL
  47. LOG_BITS_PIX   DW      1          ;LOG OF ABOVE
  48. MODULO_PIX     DW      3          ;NUMBER OF BITS TO RETAIN FOR MOD
  49. VIDEO_SEG      DW      0          ;SEGMENT VAL OF VIDEO MEMORY
  50. CAN_VIDEO      DW      0          ;CAN WE WRITE INTO VIDEO
  51. DISPLAY_PROC   DD      0          ;IF NOT WHO WILL
  52.                .XLIST
  53.                SUBTTL      STRUCTURE DEFINITIONS
  54.                .LIST
  55.                PAGE +
  56. ;
  57. ; THE POINT STRUCTURE
  58. ;
  59. P              STRUC
  60. X              DW    ?            ; X COORDINATE
  61. Y              DW    ?            ; Y COORDINATE
  62. P              ENDS
  63. ;
  64. ; THE RECTANGLE STRUCTURE
  65. ;
  66. RECT           STRUC
  67. O_X            DW    ?            ; UPPER LEFT X COOR
  68. O_Y            DW    ?            ; UPPER LEFT Y COOR
  69. C_X            DW    ?            ; LOWER RIGHT X COOR
  70. C_Y            DW    ?            ; LOWER RIGHT Y COOR
  71. RECT           ENDS
  72. ;
  73. ; THE BITMAP STRUCTURE
  74. ;
  75. BITMAP         STRUC
  76. BASE           DD    ?            ; POINTER TO BITMAP DATA
  77. BM_WIDTH       DW    ?            ; WIDTH OF DATA IN WORDS
  78. BM_O_X         DW    ?            ; RECTANGLE DEFINING DATA AREA
  79. BM_O_Y         DW    ?            ; RECTANGLE DEFINING DATA AREA
  80. BM_C_X         DW    ?            ; RECTANGLE DEFINING DATA AREA
  81. BM_C_Y         DW    ?            ; RECTANGLE DEFINING DATA AREA
  82. BM_OBS         DD    ?            ; POINTER TO OBSCURED NODE
  83. BM_ENDOBS      DD    ?            ; POINTER TO LAST OBSCURED NODE
  84. BITMAP         ENDS
  85. ;
  86. ; PARAMETERS PASSED FROM 'C' ROUTINES
  87. ;
  88. PARMS          STRUC
  89. DUMMY_PARM1    DD    ?
  90. DUMMY_PARM2    DW    ?
  91. SOURCE_PARM    DD    ?            ;POINTER TO SOURCE BITMAP
  92. RECT_PARM      DD    ?            ;POINTER TO RECTANGLE DEFINING COPY
  93. DEST_PARM      DD    ?            ;POINTER TO DESTINATION BITMAP
  94. POINT_PARM     DD    ?            ;POINTER TO POINT TO START IN DEST
  95. HTONE_PARM     DD    ?            ;POINTER TO HALFTONE BITMAP
  96. FUNCT_PARM     DW    ?            ;FUNCTION TO PERFORM (BITBLT OP CODE)
  97. PARMS          ENDS
  98.                .XLIST
  99.                SUBTTL    BITBLT OPERATION CODE DEFINITIONS
  100.                .LIST
  101.                PAGE  +
  102. ;
  103. ;*********************************************************************
  104. ;                                                                    *
  105. ;  EQUATES FOR BITBLT OPERATION CODES                                *
  106. ;                                                                    *
  107. ;                                                                    *
  108. ;                                                                    *
  109. ;*********************************************************************
  110. ;
  111. OP_ZERO        EQU   0
  112. OP_SANDD       EQU   1
  113. OP_SANDND      EQU   2
  114. OP_S           EQU   3
  115. OP_NSANDD      EQU   4
  116. OP_D           EQU   5
  117. OP_SXORD       EQU   6
  118. OP_SORD        EQU   7
  119. OP_NSANDND     EQU   8
  120. OP_NSXORD      EQU   9
  121. OP_ND          EQU   10
  122. OP_SORND       EQU   11
  123. OP_NS          EQU   12
  124. OP_NSORD       EQU   13
  125. OP_NSORND      EQU   14
  126. OP_ONES        EQU   15
  127.                .XLIST
  128.                SUBTTL      CODE TEMPLATES----ROTATE CODES
  129.                .LIST
  130.                PAGE  +
  131. ;
  132. ;*********************************************************************
  133. ;                                                                    *
  134. ;   THE FOLLOWING ARE CODE TEMPLATES USED TO MODIFY THE              *
  135. ; UGLY HORIZONTAL LOOP CODE.                                         *
  136. ;                                                                    *
  137. ;*********************************************************************
  138. ;
  139. ;*********************************************************************
  140. ;                                                                    *
  141. ;   THE FOLLOWING TABLE IS USED TO DYNAMICALLY ALTER THE             *
  142. ; ROTATE CODE IN THE UGLY HORIZONTAL COPY CODE.                      *
  143. ; ROTATE_LEFT[SHIFT_COUNT] YIELDS THE STARTING ADDRESS OF THE        *
  144. ; STREAM OF INSTRUCTIONS TO COPY INTO THE HORZ. CODE                 *
  145. ; NOTE THAT THE MOVE IS USED INSTEAD OF NOP BECAUSE NOP TAKES        *
  146. ; 3 CLOCKS TO EXECUTE, MOV ONLY 2 CLOCKS                             *
  147. ;                                                                    *
  148. ; THE MAXIMUM ROTATE COUNT IS 16 BITS.................BUT THE        *
  149. ;CODE WHICH WRITES TO ROTATE STREAMS DETECTS ROTATES OVER 8 BITS     *
  150. ;AND REPLACES THEM WITH AN OPPOSITE DIRECTION ROTATE OF 16-COUNT.    *
  151. ;                                                                    *
  152. ;*********************************************************************
  153. ;
  154.                EVEN
  155. ROTATE_LEFT:
  156.                ROL    AX,1        ; INDEX TO HERE FOR 8 BIT ROTATE
  157.                ROL    AX,1
  158.                ROL    AX,1        ; INDEX HERE FOR 6 BIT ROTATE
  159.                ROL    AX,1
  160.                ROL    AX,1        ; INDEX HERE FOR 4 BIT ROTATE
  161.                ROL    AX,1
  162.                ROL    AX,1        ; INDEX HERE FOR 2 BIT ROTATE
  163.                ROL    AX,1
  164.                MOV    AX,AX       ; NEVER INDEX HERE. SPECIAL COPY
  165.                MOV    AX,AX       ; LOOP FOR ALIGNED WORDS
  166.                MOV    AX,AX
  167.                MOV    AX,AX
  168.                MOV    AX,AX
  169.                EVEN
  170. ROTATE_RIGHT:
  171.                ROR    AX,1        ; INDEX TO HERE FOR 8 BIT ROTATE
  172.                ROR    AX,1
  173.                ROR    AX,1        ; INDEX HERE FOR 6 BIT ROTATE
  174.                ROR    AX,1
  175.                ROR    AX,1        ; INDEX HERE FOR 4 BIT ROTATE
  176.                ROR    AX,1
  177.                ROR    AX,1        ; INDEX HERE FOR 2 BIT ROTATE
  178.                ROR    AX,1
  179.                MOV    AX,AX       ; NEVER INDEX HERE. SPECIAL COPY
  180.                MOV    AX,AX       ; LOOP FOR ALIGNED WORDS
  181.                MOV    AX,AX
  182.                MOV    AX,AX
  183.                MOV    AX,AX
  184.                .XLIST
  185.                SUBTTL      CODE TEMPLATES----DO PRECHARGE CODE
  186.                .LIST
  187.                PAGE  +
  188. ;
  189. ;*********************************************************************
  190. ;                                                                    *
  191. ;   THE FOLLOWING TABLE IS USED TO DYNAMICALLY ALTER THE             *
  192. ; LEAD INTO THE SECOND WORD FETCH OF THE HORIZ COPY CODE.            *
  193. ;                                                                    *
  194. ;  IF 2 SOURCE WORDS ARE NEEDED TO WRITE THE FIRST DESTINATION       *
  195. ; WORD, THE SECOND WORD NEEDS TO BE FETCHED AND ROTATED, THEN        *
  196. ; MERGED WITH THE FIRST WORD. IF THE SECOND WORD IS NOT NEEDED,      *
  197. ; THEN A SHORT JUMP IS WRITTEN OVER THE LODSW AND THE OPCODE         *
  198. ; FOR THE FIRST ROTATE INSTRUCTION TO SKIP THE SECOND WORD FETCH     *
  199. ; AND MERGE CODE---THIS IS THE SKIP ENTRY.                           *
  200. ;                                                                    *
  201. ;  IF A PRECHARGE IS NECESSARY, THEN THE LODSW MUST BE WRITTEN       *
  202. ; BACK INTO THE SECOND WORD FETCH AREA (THE ROTATE CODE WILL         *
  203. ; REWRITE THE OFFSET OF THE JUMP IF THE OPCODE FOR THE 1ST           *
  204. ; ROTATE WAS DESTROYED)---THIS IS THE LOAD ENTRY                     *
  205. ;                                                                    *
  206. ;*********************************************************************
  207. ;
  208. LOAD_CODE:
  209.                LODSW
  210.                EVEN
  211. SKIP           DB      0,0        ; WRITE CODE FOR JMP SHORT NO_PRCHRG
  212.                .XLIST
  213.                SUBTTL      CODE TEMPLATES----BITBLT OPERATION CODES
  214.                .LIST
  215.                PAGE  +
  216. ;
  217. ;*********************************************************************
  218. ;                                                                    *
  219. ;    THE FOLLOWING TABLE IS INDEXED BY THE OPERATION CODE. IT IS     *
  220. ;  USED TO REWRITE THE OPERATION PORTION OF THE HORIZONTAL CODE      *
  221. ;   EACH ENTRY IS 8 BYTES LONG (3 SHIFTS LEFT ON INDEX)              *
  222. ;                                                                    *
  223. ;   WE DO THIS INSTEAD OF A GENERAL ROUTINE (MERGE) TO SAVE          *
  224. ; A LOT OF TIME.                                                     *
  225. ;                                                                    *
  226. ;                                                                    *
  227. ;     THIS TABLE IS FOR FORWARD REFERENCES  A DUPLICATE FOLLOWS      *
  228. ;  FOR BACKWARD COPYING                                              *
  229. ;*********************************************************************
  230. ;
  231.                EVEN
  232. OPN_LOOP_F     EQU     $
  233. CODE_ZERO_F    DB      8 DUP(0)
  234. S_AND_D_F      EQU     $
  235.                AND     ES:[DI],AX
  236.                INC     DI
  237.                INC     DI
  238.                NOP
  239.                MOV     AX,AX
  240. S_AND_ND_F     EQU     $
  241.                NOT     AX
  242.                OR      AX,ES:[DI]
  243.                NOT     AX
  244.                STOSW
  245. S_F            EQU     $
  246.                STOSW
  247.                NOP
  248.                MOV     AX,AX
  249.                MOV     AX,AX
  250.                MOV     AX,AX
  251. NS_AND_D_F     EQU     $
  252.                NOT     AX
  253.                AND     ES:[DI],AX
  254.                INC     DI
  255.                INC     DI
  256.                NOP
  257. D_F            EQU     $
  258.                DB      8 DUP(0)
  259. S_XOR_D_F      EQU     $
  260.                XOR     ES:[DI],AX
  261.                INC     DI
  262.                INC     DI
  263.                MOV     AX,AX
  264.                NOP
  265.                PAGE
  266. S_OR_D_F       EQU     $
  267.                OR      ES:[DI],AX
  268.                INC     DI
  269.                INC     DI
  270.                NOP
  271.                MOV     AX,AX
  272. NS_AND_ND_F    EQU     $
  273.                OR      AX,ES:[DI]
  274.                NOT     AX
  275.                STOSW
  276.                MOV     AX,AX
  277. NS_XOR_D_F     EQU     $
  278.                NOT     AX
  279.                XOR     ES:[DI],AX
  280.                INC     DI
  281.                INC     DI
  282.                NOP
  283. ND_F           EQU     $
  284.                DB      8 DUP(0)
  285. S_OR_ND_F      EQU     $
  286.                NOT     AX
  287.                AND     AX,ES:[DI]
  288.                NOT     AX
  289.                STOSW
  290. NS_F           EQU     $
  291.                NOT     AX
  292.                STOSW
  293.                NOP
  294.                MOV     AX,AX
  295.                MOV     AX,AX
  296. NS_OR_D_F      EQU     $
  297.                NOT     AX
  298.                OR      ES:[DI],AX
  299.                INC     DI
  300.                INC     DI
  301.                NOP
  302. NS_OR_ND_F     EQU     $
  303.                AND     ES:[DI],AX
  304.                NOT     AX
  305.                STOSW
  306.                MOV     AX,AX
  307. CODE_ONES_F    EQU     $
  308.                DB      8 DUP(0)
  309.                PAGE
  310. ;
  311. ;*********************************************************************
  312. ;                                                                    *
  313. ;    THE FOLLOWING TABLE IS INDEXED BY THE OPERATION CODE. IT IS     *
  314. ;  USED TO REWRITE THE OPERATION PORTION OF THE HORIZONTAL CODE      *
  315. ;   EACH EHTRY IS 8 BYTES LONG (3 SHIFTS LEFT ON INDEX)              *
  316. ;                                                                    *
  317. ;     THIS TABLE IS FOR COPYING BACKWARDS                            *
  318. ;                                                                    *
  319. ;*********************************************************************
  320. ;
  321.                EVEN
  322. OPN_LOOP_B     EQU     $
  323. CODE_ZERO_B    DB      8 DUP(0)
  324. S_AND_D_B      EQU     $
  325.                AND     ES:[DI],AX
  326.                DEC     DI
  327.                DEC     DI
  328.                NOP
  329.                MOV     AX,AX
  330. S_AND_ND_B     EQU     $
  331.                NOT     AX
  332.                OR      AX,ES:[DI]
  333.                NOT     AX
  334.                STOSW
  335. S_B            EQU     $
  336.                STOSW
  337.                NOP
  338.                MOV     AX,AX
  339.                MOV     AX,AX
  340.                MOV     AX,AX
  341. NS_AND_D_B     EQU     $
  342.                NOT     AX
  343.                AND     ES:[DI],AX
  344.                DEC     DI
  345.                DEC     DI
  346.                NOP
  347. D_B            EQU     $
  348.                DB      8 DUP(0)
  349. S_XOR_D_B      EQU     $
  350.                XOR     ES:[DI],AX
  351.                DEC     DI
  352.                DEC     DI
  353.                MOV     AX,AX
  354.                NOP
  355.                PAGE
  356. S_OR_D_B       EQU     $
  357.                OR      ES:[DI],AX
  358.                DEC     DI
  359.                DEC     DI
  360.                NOP
  361.                MOV     AX,AX
  362. NS_AND_ND_B    EQU     $
  363.                OR      AX,ES:[DI]
  364.                NOT     AX
  365.                STOSW
  366.                MOV     AX,AX
  367. NS_XOR_D_B     EQU     $
  368.                NOT     AX
  369.                XOR     ES:[DI],AX
  370.                DEC     DI
  371.                DEC     DI
  372.                NOP
  373. ND_B           EQU     $
  374.                DB      8 DUP(0)
  375. S_OR_ND_B      EQU     $
  376.                NOT     AX
  377.                AND     AX,ES:[DI]
  378.                NOT     AX
  379.                STOSW
  380. NS_B           EQU     $
  381.                NOT     AX
  382.                STOSW
  383.                NOP
  384.                MOV     AX,AX
  385.                MOV     AX,AX
  386. NS_OR_D_B      EQU     $
  387.                NOT     AX
  388.                OR      ES:[DI],AX
  389.                DEC     DI
  390.                DEC     DI
  391.                NOP
  392. NS_OR_ND_B     EQU     $
  393.                AND     ES:[DI],AX
  394.                NOT     AX
  395.                STOSW
  396.                MOV     AX,AX
  397. CODE_ONES_B    EQU     $
  398.                DB      8 DUP(0)
  399.                PAGE
  400. ;
  401. ;*********************************************************************
  402. ;                                                                    *
  403. ;    THE FOLLOWING TABLE IS INDEXED BY THE OPERATION CODE. IT IS     *
  404. ;  USED TO REWRITE THE OPERATION PORTION OF THE HORIZONTAL PROLOG    *
  405. ;  AND EPILOG   ASSUMES SOURCE IN BX, DESTINATION IN AX EACH ENTRY   *
  406. ;  8 BYTES AS BEFORE (ONLY FIRST 6 USED)                             *
  407. ;*********************************************************************
  408. ;
  409.                EVEN
  410. OPN_PRO_EPI    EQU     $
  411. CODE_ZERO      EQU     $            ; ALL ZEROS (DONE IN SPECIAL CODE)
  412.                DB      8 DUP(0)
  413. S_AND_D        EQU     $
  414.                AND     AX,BX
  415.                MOV     AX,AX
  416.                MOV     AX,AX
  417.                MOV     AX,AX
  418. S_AND_ND       EQU     $
  419.                NOT     AX
  420.                AND     AX,BX
  421.                MOV     AX,AX
  422.                MOV     AX,AX
  423. S              EQU     $
  424.                MOV     AX,BX
  425.                MOV     AX,AX
  426.                MOV     AX,AX
  427.                MOV     AX,AX
  428. NS_AND_D       EQU     $
  429.                NOT     BX
  430.                AND     AX,BX
  431.                MOV     AX,AX
  432.                MOV     AX,AX
  433. D              EQU     $
  434.                DB      8 DUP(0)
  435.                PAGE
  436. S_XOR_D        EQU     $
  437.                XOR     AX,BX
  438.                MOV     AX,AX
  439.                MOV     AX,AX
  440.                MOV     AX,AX
  441. S_OR_D         EQU     $
  442.                OR      AX,BX
  443.                MOV     AX,AX
  444.                MOV     AX,AX
  445.                MOV     AX,AX
  446. NS_AND_ND      EQU     $
  447.                OR      AX,BX
  448.                NOT     AX
  449.                MOV     AX,AX
  450.                MOV     AX,AX
  451. NS_XOR_D       EQU     $
  452.                NOT     BX
  453.                XOR     AX,BX
  454.                MOV     AX,AX
  455.                MOV     AX,AX
  456. ND             EQU     $
  457.                DB      8 DUP(0)
  458. S_OR_ND        EQU     $
  459.                NOT     AX
  460.                OR      AX,BX
  461.                MOV     AX,AX
  462.                MOV     AX,AX
  463. NS             EQU     $
  464.                NOT     BX
  465.                MOV     AX,BX
  466.                MOV     AX,AX
  467.                MOV     AX,AX
  468. NS_OR_D        EQU     $
  469.                NOT     BX
  470.                OR      AX,BX
  471.                MOV     AX,AX
  472.                MOV     AX,AX
  473. NS_OR_ND       EQU     $
  474.                AND     AX,BX
  475.                NOT     AX
  476.                MOV     AX,AX
  477.                MOV     AX,AX
  478. CODE_ONES      EQU     $
  479.                DB      8 DUP(0)
  480.                .XLIST
  481.                SUBTTL      MERGE MASKS
  482.                .LIST
  483.                PAGE  +
  484. ;
  485. ;*********************************************************************
  486. ;                                                                    *
  487. ;      THE FOLLOWING ARE THE MASKS TO BE USED IN THE ROTATE AND      *
  488. ; MERGE FUNCTIONS OF THE INNER HORZ. COPY CODE                       *
  489. ;  THIS TABLE ASSUMES 2 BITS PER PIXEL                               *
  490. ;                                                                    *
  491. ;          NEED TO USE BYTE TO MATCH                                 *
  492. ;         THE WAY THE PIXELS ARE LOADED INTO                         *
  493. ;         A REGISTER FROM MEMORY IE                                  *
  494. ;           0 1 2 3 4 5 6 7  IN ONE WORD OF MEM                      *
  495. ;           4 5 6 7 0 1 2 3  IS THIS IN REG                          *
  496. ;*********************************************************************
  497. ;
  498.                EVEN
  499. MASKS          DB      00H,00H    ;
  500.                DB      00H,01H    ;
  501.                DB      00H,03H    ;
  502.                DB      00H,07H    ;
  503.                DB      00H,0FH    ;
  504.                DB      00H,1FH    ;
  505.                DB      00H,3FH    ;
  506.                DB      00H,7FH    ;
  507.                DB      00H,0FFH    ;
  508.                DB      01H,0FFH    ;
  509.                DB      03H,0FFH    ;
  510.                DB      07H,0FFH    ;
  511.                DB      0FH,0FFH    ;
  512.                DB      1FH,0FFH    ;
  513.                DB      3FH,0FFH    ;
  514.                DB      7FH,0FFH    ;
  515. BACK_MASKS     DB     0FFH,0FFH    ;
  516.                DB      7FH,0FFH    ;
  517.                DB      3FH,0FFH    ;
  518.                DB      1FH,0FFH    ;
  519.                DB      0FH,0FFH    ;
  520.                DB      07H,0FFH    ;
  521.                DB      03H,0FFH    ;
  522.                DB      01H,0FFH    ;
  523.                DB      00H,0FFH    ;
  524.                DB      00H,7FH    ;
  525.                DB      00H,3FH    ;
  526.                DB      00H,1FH    ;
  527.                DB      00H,0FH    ;
  528.                DB      00H,07H    ;
  529.                DB      00H,03H    ;
  530.                DB      00H,01H    ;
  531.                DB      00H,00H    ;
  532.                .XLIST
  533.                SUBTTL      MASK GET PROCEDURES
  534.                .LIST
  535.                PAGE  +
  536. GET_MASK       PROC  NEAR
  537.                PUSH  BX            ;SAVE BX,CX
  538.                PUSH  CX
  539.                XOR   CX,CX         ;CLEAR CX
  540.                MOV   CX,BITS_PIXEL ;GET BITS PER PIXEL
  541.                INC   CX            ;MASKS ARE WORDS
  542.                SAL   BX,CL         ;MULT INDEX BY (BITS_PIXEL+1)*2
  543.                MOV   AX,WORD PTR MASKS[BX]  ;GET MASK
  544.                POP   CX            ;RESTORE REGS
  545.                POP   BX
  546.                RET
  547. GET_MASK       ENDP
  548. ;
  549. ;
  550. ;
  551. GET_BMASK      PROC  NEAR
  552.                PUSH  BX            ;SAVE BX,CX
  553.                PUSH  CX
  554.                XOR   CX,CX         ;CLEAR CX
  555.                MOV   CX,BITS_PIXEL ;GET BITS PER PIXEL
  556.                INC   CX            ;MASKS ARE WORDS
  557.                SAL   BX,CL         ;MULT INDEX BY (BITS_PIXEL+1)*2
  558.                MOV   AX,WORD PTR BACK_MASKS[BX]  ;GET MASK
  559.                POP   CX            ;RESTORE REGS
  560.                POP   BX
  561.                RET
  562. GET_BMASK      ENDP
  563.                .XLIST
  564.                SUBTTL      STATIC STORAGE AREAS
  565.                .LIST
  566.                PAGE  +
  567.                EVEN
  568. ;
  569. ; PARAMETERS PASSED
  570. ;
  571. OPN_CODE       DB      0          ; BITBLT OPERATION CODE (0-16)
  572.                DB      0          ; ALIGN TO WORD BOUNDRY
  573. SOURCE_PTR     DD      0          ; POINTER TO SOURCE BITMAP
  574. DEST_PTR       DD      0          ; POINTER TO DESTINATION BITMAP
  575. SAVE_PTR       DD      0          ; IF CAN'T COPY TO VIDEO, SAVE OLD
  576. HTONE_PTR      DD      0          ; POINTER TO HALFTONE/COLOR BITMAP
  577. RECT_PTR       DD      0          ; POINTER TO CLIPPING RECTANGLE
  578. POINT_PTR      DD      0          ; POINTER TO POINT IN DEST TO START
  579. ;
  580. ; INTERNAL VARIABLES
  581. ;
  582. S_X            DW      0          ; SOURCE X COOR
  583. S_Y            DW      0          ; SOURCE Y COOR
  584. SOURCE_INDX    DW      0          ; OFFSET INTO SOURCE FOR COPY
  585. DEST_INDX      DW      0          ; OFFSET INTO DESTINATION FOR COPY
  586. D_X            DW      0          ; DESTINATION X COOR
  587. D_Y            DW      0          ; DESTINATION Y COOR
  588. DIRECTION      DW      0          ; LEFT OR RIGHT ROTATE
  589. COUNT          DW      0          ; ROTATE COUNT IN BITS
  590. SSKEW_RIGHT    DW      0          ; NUMBER OF PIXELS OFF ON RIGHT
  591. SSKEW_LEFT     DW      0          ; NUMBER OF PIXELS OFF ON LEFT
  592. DSKEW_RIGHT    DW      0          ; NUMBER OF PIXELS OFF ON RIGHT
  593. DSKEW_LEFT     DW      0          ; NUMBER OF PIXELS OFF ON LEFTT
  594. PRECHRG        DW      0          ; IF 1 THEN USE PRECHARGE CODE
  595. NO_PREC        EQU     0
  596. VDIR           DW      0          ; IF 1 THEN BACKWARD VERT COPY
  597. FORWARD        EQU     0
  598. HDIR           DW      0          ; IF 1 THEN BACKWARD HORZ COPY
  599. WIDTH_PIX      DW      0          ; WIDTH OF RECTANGLE CLIP IN PIXELS
  600. HEIGHT_PIX     DW      0          ; HEIGHT OF RECTANGLE CLIP IN PIXELS
  601. NWORDS         DW      0          ; NUMBER OF WORDS FOR HORZ COPY
  602. MAX_VECTOR     EQU   64
  603. V_WORD_CNT     DW      0          ; NUMBER OF HORZ SCANS
  604. DELTA_S        DW      0          ; AMOUNT TO GET TO NEXT LINE
  605. DELTA_D        DW      0          ; AMOUNT TO GET TO NEXT LINE
  606. ALIGN_PRMASK   DW      0          ; PROLOGUE MASK FOR ALIGNED COPY
  607. ALIGN_EPMASK   DW      0          ; EPILOGUE MASK FOR ALIGNED COPY
  608. CURR_PTR_S     DD      0          ; POINTER TO 1ST WORD OF CURRENT LINE
  609. CURR_PTR_D     DD      0          ; POINTER TO 1ST WORD OF CURRENT LINE
  610. HTONE_INDX     DB      0          ; INDEX INTO HTONE_VEC (BYTE)
  611. HTONE_MOD      DB      0          ; NUMBER OF BITS TO RETAIN FOR MODULO
  612. HTONE_VEC      DW    MAX_VECTOR DUP(0)  ; VECTOR OF HALFTONE WORDS
  613. DS_SAVE        DW      ?          ; SAVE AREA FOR DS
  614. ES_SAVE        DW      ?          ; SAVE AREA FOR ES
  615. SAVE_SS        DW      ?          ; SAVE AREA FOR SS
  616. SAVE_SP        DW      ?          ; SAVE AREA FOR SP
  617. BP_SAVE        DW      ?          ; SAVE AREA FOR BP
  618.                .XLIST
  619.                SUBTTL      BITBLT ENTRY POINT CODE
  620.                .LIST
  621.                PAGE  +
  622.                EVEN
  623. BITBLT_MAIN:
  624. ;*********************************************************************
  625. ;                                                                    *
  626. ;        BITBLT MAIN ENTRY POINT                                     *
  627. ;
  628. ;*********************************************************************
  629. ;
  630. ;
  631. ; GET PARAMETERS FROM 'C' CALLING ROUTINE AND VERIFY PARMS
  632. ;
  633.                CALL    C_INTFACE
  634.                JC        BITBLT_EXIT1  ; IF ERROR, EXIT
  635. ;
  636. ; CLIP TO SMALLEST RECTANGLE
  637. ;
  638.                CALL    CLIP_RECT
  639.                JC        BITBLT_EXIT1  ; IF ERROR, EXIT
  640. ;
  641. ; COMPUTE THE SOURCE AND DESTINATION SKEWS
  642. ;
  643.                CALL    CALC_SKEWS
  644. ;
  645. ; CHECK FOR SOURCE DESTINATION OVERLAP
  646. ;
  647.                CALL    CHK_OVLAP
  648. ;
  649. ;   CALCULATE NUMBER OF WORDS PER HORIZONTAL SCAN
  650. ;
  651.                CALL    CALC_NWORD
  652. ;
  653. ; CALCULATE STARTING OFFSETS
  654. ;
  655.                CALL    CALC_START
  656. ;
  657. ; CALCULATE AMOUNT TO ADD TO GET TO NEXT SCAN LINE
  658. ;
  659.                CALL    CALC_DELTA
  660. ;
  661. ; BUILD HALFTONE VECTOR AND INDEX FROM HALFTONE POINTER
  662. ;
  663.                CALL    HTONE_GET
  664.                PAGE
  665. ;
  666. ; IF BITBLT CODE IS D OR NOT D  THEN DO FAST VERSION
  667. ;
  668.                MOV     AL,OPN_CODE
  669.                CMP     AL,OP_D    ; OP CODE OF D
  670.                JE        FAST_COPY
  671.                CMP     AL,OP_ND   ; OP CODE OF ~D
  672.                JE        FAST_COPY
  673.                CMP     AL,OP_ZERO
  674.                JE        FAST_COPY
  675.                CMP     AL,OP_ONES
  676.                JE        FAST_COPY
  677. ;
  678. ; IF HERE THEN NOT SIMPLE CODE
  679. ;
  680. ;
  681. ;   CHECK IF SOURCE AND DEST ARE ALIGNED
  682. ;    IF THEY ARE THEN DO FAST VERSION
  683. ;
  684.                MOV   AX,SSKEW_LEFT
  685.                CMP   AX,DSKEW_LEFT
  686.                JE       ALIGN_COPY
  687.                CALL     COPY_NALIGN
  688.                JMP      SHORT BITBLT_EXIT
  689. ALIGN_COPY:
  690.                CALL     COPY_ALIGN
  691.                JMP      SHORT BITBLT_EXIT
  692. FAST_COPY:
  693.                CALL     FAST_COPY
  694. BITBLT_EXIT:
  695. ;
  696. ; IF BITBLT DIDN'T DO ITS THING TO THE DISPLAY, COPY THE DEST BITMAP
  697. ; TO THE VIDEO USING THE PROCEDURE PROVIDED AT INITALIZATION
  698. ;
  699.                CALL     COPY_DISPLAY
  700. BITBLT_EXIT1:
  701. ;
  702. ; CLEANUP REGS AND RET
  703. ;
  704.                MOV     SS,SAVE_SS      ; RESTORE SS
  705.                MOV     BP,BP_SAVE      ; RESTORE BP
  706.                MOV     DS,CS:DS_SAVE   ; RESTORE DS
  707.                MOV     SP,BP           ; RESTORE SP
  708.                POP     BP              ; RESTORE BP
  709.                RET
  710.                .XLIST
  711.                SUBTTL    INTERFACE TO 'C' ROUTINES AND ERROR CHECK
  712.                .LIST
  713.                PAGE  +
  714. C_INTFACE      PROC  NEAR
  715. ;*********************************************************************
  716. ;                                                                    *
  717. ; GET PARAMETERS FROM STACK AND VERIFY                               *
  718. ;                                                                    *
  719. ;*********************************************************************
  720. ;
  721.                PUSH  BP           ; SAVE BP
  722.                MOV   BP,SP
  723.                MOV   DI,OFFSET SOURCE_PTR      ;SET DI TO INTERNAL PARMS
  724.                LES   SI,[BP].SOURCE_PARM
  725.                MOV   CS:[DI],SI                ; SAVE SOURCE BITMAP PTR
  726.                INC   DI
  727.                INC   DI
  728.                MOV   CS:[DI],ES
  729.                INC   DI
  730.                INC   DI
  731.                LES   SI,[BP].DEST_PARM
  732.                MOV   CS:[DI],SI                ; SAVE DEST BITMAP PTR
  733.                INC   DI
  734.                INC   DI
  735.                MOV   CS:[DI],ES
  736.                INC   DI
  737.                INC   DI
  738.                LES   SI,[BP].HTONE_PARM
  739.                MOV   CS:[DI],SI                ; SAVE HALFTONE BITMAP PTR
  740.                INC   DI
  741.                INC   DI
  742.                MOV   CS:[DI],ES
  743.                INC   DI
  744.                INC   DI
  745.                LES   SI,[BP].RECT_PARM
  746.                MOV   CS:[DI],SI                ; SAVE RECTANGLE POINTER
  747.                INC   DI
  748.                INC   DI
  749.                MOV   CS:[DI],ES
  750.                INC   DI
  751.                INC   DI
  752.                LES   SI,[BP].POINT_PARM
  753.                MOV   CS:[DI],SI                ; SAVE POINT POINTER
  754.                INC   DI
  755.                INC   DI
  756.                MOV   CS:[DI],ES
  757.                MOV   AX,[BP].FUNCT_PARM        ; SAVE BITBLT OPCODE
  758.                MOV   WORD PTR CS:OPN_CODE,AX
  759.                MOV   CS:DS_SAVE,DS             ;GET DS TO CODE SEG
  760.                MOV   AX,CS
  761.                MOV   DS,AX
  762.                MOV   SAVE_SS,SS
  763.                MOV   BP_SAVE,BP
  764.                PAGE
  765. ;
  766. ; NOW VERIFY THE PARMS
  767. ;
  768.                LES   SI,SOURCE_PTR
  769.                MOV   AX,ES
  770.                OR    AX,SI
  771.                JNZ   SOURCE_OK    ;IF SOURCE =0
  772.                MOV   AL,OPN_CODE  ;  IS OP CODE = ALL ZEROES?
  773.                CMP   AL,OP_ZERO
  774.                JE     SOURCE_OK   ; YES, OK
  775.                CMP   AL,OP_ONES   ;  OP CODE = ALL ONES?
  776.                JE     SOURCE_OK   ; YES, OK
  777.                CMP   AL,OP_D      ;  OP CODE = D
  778.                JE     SOURCE_OK   ; YES, OK
  779.                CMP   AL,OP_ND     ; OP CODE = ~D
  780.                JNE    BAD_PARM    ; INVALID SOURCE PARM RESTORE AND RET
  781. SOURCE_OK:
  782.                LES   SI,DEST_PTR  ; CHECK FOR NULL DESTINATION
  783.                MOV   AX,ES
  784.                OR    AX,SI
  785.                JZ     BAD_PARM
  786. DEST_OK:
  787.                LES   SI,RECT_PTR  ; CHECK FOR NULL RECTANGLE PTR
  788.                MOV   AX,ES
  789.                OR    AX,SI
  790.                JZ     BAD_PARM
  791. RECT_OK:
  792.                LES   SI,POINT_PTR ; CHECK FOR NULL POINT PTR
  793.                MOV   AX,ES
  794.                OR    AX,SI
  795.                JZ     BAD_PARM
  796. POINT_OK:
  797. ;
  798. ; ALL PARMS OK, CLEAR CARRY AND RETURN
  799. ;
  800.                CLC
  801.                RET
  802. BAD_PARM:
  803. ;
  804. ; BAD PARAMETER. SET CARRY AND RETURN
  805. ;
  806.                STC
  807.                RET
  808. C_INTFACE      ENDP
  809.                .XLIST
  810.                SUBTTL    CLIP TO DEFINING RECTANGLE ROUTINE
  811.                .LIST
  812.                PAGE  +
  813. CLIP_RECT      PROC  NEAR
  814. ;
  815. ;*********************************************************************
  816. ;                                                                    *
  817. ;  CLIP CLIPS THE BITBLT OPERATION TO AVOID COPYING BEYOND THE       *
  818. ; BOUNDS OF THE DESTINATION BITMAP                                   *
  819. ;                                                                    *
  820. ;*********************************************************************
  821. ;
  822. ; COMPUTE WIDTH IN PIXELS
  823. ;
  824.                LES   SI,RECT_PTR
  825.                MOV   AX,ES:[SI].O_X
  826.                MOV   S_X,AX
  827.                MOV   BX,ES:[SI].C_X
  828.                SUB   AX,BX
  829.                MOV   CX,AX
  830.                MOV   WIDTH_PIX,AX
  831. ;
  832. ; COMPUTE HEIGHT IN PIXELS
  833. ;
  834.                MOV   AX,ES:[SI].O_Y
  835.                MOV   S_Y,AX
  836.                MOV   BX,ES:[SI].C_Y
  837.                SUB   AX,BX
  838.                MOV   HEIGHT_PIX,AX
  839. ;
  840. ; IF WIDTH OR HEIGHT <=0 THEN EXIT
  841. ;
  842.                XOR   DX,DX
  843.                CMP   AX,DX
  844.                JLE    CLIP_FEXIT
  845.                CMP   CX,DX
  846.                JLE    CLIP_FEXIT
  847.                PAGE
  848. ;
  849. ; VALID H AND W, NOW MAKE SURE WE DO NOT GO BEYOND DESTINATION LIMIT
  850. ;
  851. ; FIRST CHECK WIDTH, IE IF P.X+WIDTH>DEST C_X
  852. ;
  853.                LES   SI,DEST_PTR
  854.                MOV   DX,AX        ; SAVE HEIGHT
  855.                MOV   AX,ES:[SI].C_X
  856.                LES   DI,POINT_PTR
  857.                MOV   BX,ES:[DI].X
  858.                MOV   D_X,BX
  859.                ADD   BX,CX        ; ADD X TO WIDTH
  860.                CMP   BX,AX
  861.                JLE     CHECK_H
  862.                SUB   AX,D_X
  863.                MOV   WIDTH_PIX,AX  ; CORRECT WIDTH
  864. CHECK_H:
  865. ;
  866. ; NOW CHECK HEIGHT OF COPY
  867. ;
  868.                MOV   AX,ES:[SI].C_Y
  869.                MOV   BX,ES:[DI].Y
  870.                ADD   BX,DX
  871.                CMP   BX,AX
  872.                JLE   CLIP_EXIT
  873.                SUB   AX,ES:[DI].Y
  874.                MOV   HEIGHT_PIX,AX    ; CORRECT HEIGHT
  875. CLIP_EXIT:
  876.                CLC                ; CLEAR CARRY CONTINUE
  877.                RET
  878. CLIP_FEXIT:
  879.                STC                ; SET CARRY EXIT BITBLT
  880.                RET
  881. CLIP_RECT      ENDP
  882.                .XLIST
  883.                SUBTTL    CALCULATE OFFSET INTO SOURCE AND DESTINATION
  884.                .LIST
  885.                PAGE  +
  886. CALC_START     PROC  NEAR
  887. ;
  888. ;*********************************************************************
  889. ;                                                                    *
  890. ;  COMPUTE THE STARTING INDICIES INTO TO SOURCE AND DESTINATION      *
  891. ;                                                                    *
  892. ;*********************************************************************
  893. ;                                                                    *
  894.                XOR   DX,DX
  895.                LES   SI,SOURCE_PTR
  896.                CMP   SI,DX
  897.                JA    CALC_S1
  898.                MOV   AX,ES
  899.                CMP   AX,DX
  900.                JE      CALC_ZERO
  901. CALC_S1:
  902. ;
  903. ; SOURCE NOT NULL, DO FULL CALCULATION
  904. ;
  905. ; SOURCEINDEX=((SY-RECT.ORIGIN.Y)*BIT_WIDTH)+(SX/PIXELS_WORD)
  906. ;              - (RECT.ORIGIN.X/PIXELS_WORD)
  907.                MOV   CX,ES:[SI].BM_WIDTH
  908.                MOV   AX,S_Y
  909.                MOV   BX,ES:[SI].BM_O_Y
  910.                SUB   AX,BX
  911.                MUL   CL
  912.                MOV   BX,S_X
  913.                MOV   CL,BYTE PTR LOG_PIX_WRD
  914.                MOV   CH,CL
  915.                SAR   BX,CL
  916.                ADD   AX,BX
  917.                MOV   BX,ES:[SI].BM_O_X
  918.                MOV   CL,CH
  919.                SAR   BX,CL
  920.                SUB   AX,BX
  921.                MOV   SOURCE_INDX,AX
  922.                JMP     SHORT SAVE_PTRS
  923. CALC_ZERO:
  924.                XOR   AX,AX
  925.                MOV   SOURCE_INDX,AX
  926. SAVE_PTRS:
  927.                LES   SI,ES:[SI].BASE    ; GET PTR TO BITMAP DATA
  928.                ADD   SI,AX              ; ADD OFFSET TO START
  929.                MOV   WORD PTR CURR_PTR_S,SI
  930.                MOV   WORD PTR CURR_PTR_S+2,ES
  931.                PAGE
  932. ;
  933. ; NOW CALC THE START FOR THE DESTINATION
  934. ;
  935. ; DESTINDEX=((DY-RECT.ORIGIN.Y)*BIT_WIDTH)+(DX/PIXELS_WORD)
  936. ;              - (RECT.ORIGIN.X/PIXELS_WORD)
  937. ;
  938.                LES   SI,DEST_PTR
  939.                MOV   CX,ES:[SI].BM_WIDTH
  940.                MOV   AX,D_Y
  941.                MOV   BX,ES:[SI].BM_O_Y
  942.                SUB   AX,BX
  943.                MUL   CL
  944.                MOV   BX,D_X
  945.                MOV   CL,BYTE PTR LOG_PIX_WRD
  946.                MOV   CH,CL
  947.                SAR   BX,CL
  948.                ADD   AX,BX
  949.                MOV   BX,ES:[SI].BM_O_X
  950.                MOV   DX,BX
  951.                MOV   CL,CH
  952.                SAR   BX,CL
  953.                SUB   AX,BX
  954.                MOV   DEST_INDX,AX
  955.                LES   SI,ES:[SI].BASE    ; GET PTR TO BITMAP DATA
  956.                ADD   SI,AX              ; ADD OFFSET TO START
  957.                MOV   WORD PTR CURR_PTR_D,SI
  958.                MOV   WORD PTR CURR_PTR_D+2,ES
  959.                RET
  960. CALC_START     ENDP
  961.                .XLIST
  962.                SUBTTL    CALCULATE SOURCE AND DESTINATION SKEWS
  963.                .LIST
  964.                PAGE  +
  965. CALC_SKEWS     PROC  NEAR
  966. ;
  967. ;*********************************************************************
  968. ;
  969. ;  COMPUTE LEFT AND RIGHT SKEW FOR SOURCE  AND DESTINATION
  970. ;
  971. ;*********************************************************************
  972. ;
  973. ;  SSKEW_LEFT=(BM_O_X+SX) MOD PIXELS_WORD
  974. ;  SSKEW_RIGHT=(BM_O_X+SX+WIDTH_PIX) MOD PIXELS_WORD
  975. ;
  976.                MOV   BP,WORD PTR MODULO_PIX
  977.                LES   SI,SOURCE_PTR
  978.                MOV   DX,ES:[SI].BM_O_X
  979.                ADD   DX,S_X               ; BM_O_X+S_X
  980.                MOV   AX,DX
  981.                AND   AX,BP
  982.                MOV   AX,SSKEW_LEFT
  983.                ADD   DX,WIDTH_PIX
  984.                AND   DX,BP
  985.                MOV   SSKEW_RIGHT,DX
  986. ;
  987. ; NOW COMPUTE LEFT AND RIGHT SKEW FOR DESTINATION
  988. ;  DSKEW_LEFT=(BM_O_X+DX) MOD PIXELS_WORD
  989. ;  DSKEW_RIGHT=(BM_O_X+DX+WIDTH_PIX) MOD PIXELS_WORD
  990. ;
  991.                LES   SI,DEST_PTR
  992.                MOV   DX,ES:[SI].BM_O_X
  993.                ADD   DX,D_X               ; BM_O_X+S_X
  994.                MOV   AX,DX
  995.                AND   AX,BP                ; MODULO MASK
  996.                MOV   AX,DSKEW_LEFT
  997.                ADD   DX,WIDTH_PIX
  998.                AND   DX,BP
  999.                MOV   DSKEW_RIGHT,DX
  1000.                RET
  1001. CALC_SKEWS     ENDP
  1002.                .XLIST
  1003.                SUBTTL    CHECK FOR OVERLAP CONDITION AND CORRECT
  1004.                .LIST
  1005.                PAGE  +
  1006. CHK_OVLAP      PROC  NEAR
  1007. ;
  1008. ;*********************************************************************
  1009. ;                                                                    *
  1010. ;  CHECK FOR POSSIBLE OVERLAP IN COPYING INTO ITSELF                 *
  1011. ;                                                                    *
  1012. ;*********************************************************************
  1013. ;
  1014.                LES   SI,SOURCE_PTR
  1015.                MOV   AX,ES
  1016.                LES   DI,DEST_PTR
  1017.                MOV   BX,ES
  1018.                CMP   AX,BX
  1019.                JNE     OVLAP_EXIT
  1020.                CMP   DI,SI
  1021.                JNE     OVLAP_EXIT
  1022. ;
  1023. ; IF HERE BOTH SOURCE AND DESTINATION BITMAPS ARE THE SAME
  1024. ;
  1025.                XOR   DX,DX
  1026.                MOV   HDIR,DX      ; IF 0 NORMAL COPY DIRECTION HORZ
  1027.                MOV   VDIR,DX      ; IF 0 NORMAL COPY DIRECTION VERT
  1028.                DEC   DX           ; SET DX FOR BACKWARDS DIRECTION
  1029. ;
  1030. ; CHECK FOR OVERLAP IN VERTICAL DIRECTION
  1031. ;
  1032.                MOV   AX,D_Y
  1033.                MOV   BX,S_Y
  1034.                CMP   AX,BX
  1035.                JLE   OVLAP_HOR
  1036. ;
  1037. ; GOT OVERLAP IN Y
  1038. ;
  1039.                MOV   CX,HEIGHT_PIX
  1040.                DEC   CX
  1041.                ADD   AX,CX        ; D_Y=D_Y+H-1
  1042.                ADD   BX,CX        ; S_Y=S_Y+H-1
  1043.                MOV   D_Y,AX
  1044.                MOV   S_Y,BX
  1045.                MOV   VDIR,DX      ; IF 1 THEN BACKWARDS VERT COPYING
  1046. OVLAP_HOR:
  1047. ;
  1048. ; CHECK FOR OVERLAP IN HORIZONTAL DIRECTION
  1049. ;
  1050.                MOV   AX,D_X
  1051.                MOV   BX,S_X
  1052.                CMP   AX,BX
  1053.                JLE    OVLAP_EXIT
  1054.                PAGE
  1055. ;
  1056. ; HORZ COPY BACKWARD
  1057. ;
  1058.                MOV   CX,WIDTH_PIX
  1059.                DEC   CX
  1060.                ADD   AX,CX
  1061.                ADD   BX,CX
  1062.                MOV   D_X,AX
  1063.                MOV   S_X,BX
  1064.                MOV   HDIR,DX
  1065. ;
  1066. ; SWAP RIGHT AND LEFT SKEW VALUES
  1067. ;
  1068.                MOV   AX,SSKEW_RIGHT
  1069.                MOV   BX,SSKEW_LEFT
  1070.                XCHG  AX,BX
  1071.                MOV   SSKEW_RIGHT,AX
  1072.                MOV   SSKEW_LEFT,BX
  1073. ;
  1074. ; NOW DO DESTINATION
  1075.                MOV   AX,DSKEW_RIGHT
  1076.                MOV   BX,DSKEW_LEFT
  1077.                XCHG  AX,BX
  1078.                MOV   DSKEW_RIGHT,AX
  1079.                MOV   DSKEW_LEFT,BX
  1080. OVLAP_EXIT:
  1081.                RET
  1082. CHK_OVLAP      ENDP
  1083.                .XLIST
  1084.                SUBTTL    COMPUTE NUMBER OF WORDS PER HORIZONTAL SCAN
  1085.                .LIST
  1086.                PAGE  +
  1087. CALC_NWORD     PROC  NEAR
  1088. ;
  1089. ;*********************************************************************
  1090. ;                                                                    *
  1091. ; CALCULATE THE NUMBER OF WORDS IN A HORIZONTAL COPY                 *
  1092. ;                                                                    *
  1093. ;*********************************************************************
  1094. ;
  1095. ; CLEAR PRECHARGE INDICATOR
  1096. ;
  1097.                XOR   DX,DX
  1098.                MOV   PRECHRG,DX
  1099. ;
  1100. ; FORM WIDTH MINUS START MINUS 1
  1101. ;
  1102.                MOV   BX,WIDTH_PIX
  1103.                SUB   BX,SSKEW_LEFT
  1104.                DEC   BX
  1105. ;
  1106. ; BX NOW HAS NWORDS IF NO PRECHARGE
  1107. ;
  1108.                MOV   AX,SSKEW_RIGHT
  1109.                CMP   AX,DSKEW_RIGHT
  1110.                JB    NWORD_PRE
  1111. ;
  1112. ; NO PRECHARGE NEEDED
  1113. ;
  1114.                MOV   NWORDS,BX
  1115.                RET
  1116. NWORD_PRE:
  1117. ;
  1118. ; NEED TO PRECHARGE. SET INDICATOR AN DECREMENT NWORD
  1119. ;
  1120.                DEC   DX
  1121.                MOV   PRECHRG,DX
  1122.                DEC   BX
  1123.                MOV   NWORDS,BX
  1124.                RET
  1125. CALC_NWORD     ENDP
  1126.                .XLIST
  1127.                SUBTTL    CALCULATE AMOUNT TO GET TO NEXT LINE ROUTINE
  1128.                .LIST
  1129.                PAGE  +
  1130. CALC_DELTA     PROC  NEAR
  1131. ;
  1132. ;*********************************************************************
  1133. ;                                                                    *
  1134. ;    THIS ROUTINE BUILDS DELTA_S AND DELTA_D. THESE TWO QUANTITIES   *
  1135. ; ARE ADDED TO THE ENDING SCAN LINE INDICIES TO GET TO THE START OF  *
  1136. ; THE NEXT SCAN LINE                                                 *
  1137. ;                                                                    *
  1138. ;                                                                    *
  1139. ;*********************************************************************
  1140. ;
  1141.                LES   SI,SOURCE_PTR
  1142.                MOV   AX,ES:[SI].BM_WIDTH    ;GET WIDTH OF BITMAP
  1143.                XOR   CX,CX
  1144.                CMP   CX,VDIR
  1145.                JE       USE_WIDTH1
  1146.                NEG   AX                     ; IF V DIR BACKWARDS THEN
  1147.                                             ; USE -WIDTH
  1148. USE_WIDTH1:
  1149.                MOV   BX,NWORDS
  1150.                CMP   CX,PRECHRG
  1151.                JNE      DONT_INC1             ; IF PRECHARGE ALREADY
  1152.                                             ; ATE SECOND WORD, DONT INC
  1153.                INC   BX
  1154. DONT_INC1:
  1155.                CMP   CX,HDIR                ; IF H DIR BACKWARD, THEN
  1156.                JE      USE_NWORDS1            ; USE -NWORDS+(0/1)
  1157.                NEG   BX
  1158. USE_NWORDS1:
  1159.                SUB   AX,BX
  1160.                MOV   DELTA_S,AX
  1161. ;
  1162. ; NOW DO DESTINATION DELTA
  1163. ;
  1164.                LES   SI,DEST_PTR
  1165.                MOV   AX,ES:[SI].BM_WIDTH    ;GET WIDTH OF BITMAP
  1166.                XOR   CX,CX
  1167.                CMP   CX,VDIR
  1168.                JE     USE_WIDTH2
  1169.                NEG   AX                     ; IF V DIR BACKWARDS THEN
  1170.                                             ; USE -WIDTH
  1171. USE_WIDTH2:
  1172.                MOV   BX,NWORDS
  1173.                CMP   CX,PRECHRG
  1174.                JNE      DONT_INC2             ; IF PRECHARGE ALREADY
  1175.                                             ; ATE SECOND WORD, DONT INC
  1176.                INC   BX
  1177. DONT_INC2:
  1178.                CMP   CX,HDIR                ; IF H DIR BACKWARD, THEN
  1179.                JE    USE_NWORDS2            ; USE -NWORDS+(0/1)
  1180.                NEG   BX
  1181. USE_NWORDS2:
  1182.                SUB   AX,BX
  1183.                MOV   DELTA_S,AX
  1184.                RET
  1185. CALC_DELTA     ENDP
  1186.                .XLIST
  1187.                SUBTTL    UNALIGNED HORIZ COPY ROUTINE
  1188.                .LIST
  1189.                PAGE  +
  1190. COPY_NALIGN    PROC  NEAR
  1191. ;
  1192. ;*********************************************************************
  1193. ;                                                                    *
  1194. ;  PERFORM THE COPYBITS OPERATION FOR NON ALIGNED DATA               *
  1195. ;                                                                    *
  1196. ;*********************************************************************
  1197. ;
  1198. ;*********************************************************************
  1199. ;        NOTES ABOUT UNALIGNED COPYING                               *
  1200. ;                                                                    *
  1201. ; FOR THE PURPOSES OF ILLUSTRATION, CONSIDER 2 BITS/PIXEL(8 PIX/WORD)*
  1202. ; AND PRECHARGE OPERATION, IE, IT TAKES 2 SOURCE WORDS               *
  1203. ; TO GENERATE THE FIRST DESTINATION WORD.                            *
  1204. ;                                                                    *
  1205. ;                                                                    *
  1206. ;   SOURCE WORD 1              SOURCE WORD 2        SOURCE WORD 3    *
  1207. ;  *-*-*-*-*-*-*-*--RELATIVE--*-*-*-*-*-*-*-*------*-*-*-*-*-*-*-*   *
  1208. ;  | | | | | | | |    PIXEL   | | | | | | | |      | | | | | | | |   *
  1209. ;  V V V V V V V V     NOS.   V V V V V V V V      V V V V V V V V   *
  1210. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1211. ; |0|1|2|3|4|5|6|7|          |0|1|2|3|4|5|6|7|    |0|1|2|3|4|5|6|7|  *
  1212. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1213. ;                                                                    *
  1214. ;                                                                    *
  1215. ;                 8-RELATIVE PIXEL NOS(LOCAL SKEW)                  *
  1216. ;                                                                    *
  1217. ;            +----ASSUME SOURCE STARTS HERE                          *
  1218. ;            V                                                       *
  1219. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1220. ; |8|7|6|5|4|3|2|1|          |8|7|6|5|4|3|2|1|    |8|7|6|5|4|3|2|1|  *
  1221. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1222. ;                                                                    *
  1223. ;                                                                    *
  1224. ;  SKEW FACTOR IS LOCAL SOURCE SKEW-LOCAL DEST SKEW                  *
  1225. ;                                                                    *
  1226. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1227. ;              |8|7|6|5|4|3|2|1|            |8|7|6|5|4|3|2|1|        *
  1228. ;              +-+^+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1229. ;DESTINATION      |                                                  *
  1230. ;STARTS HERE------+  DEST WORD 1               DEST WORD 2           *
  1231. ;                                                                    *
  1232. ;   THEN THE SKEW, OR THE NUMBER OF PIXELS WE ARE OFF, IS -4.        *
  1233. ; SINCE THE SKEW FACTOR IS NEGATIVE WE MUST DO A PRECHARGE.          *
  1234. ; NOTE THAT THE ABSOLUTE VALUE OF THE SKEW FACTOR IS THE             *
  1235. ; NUMBER OF PIXELS WE NEED TO SHIFT TO BRING THE SOURCE AND          *
  1236. ; DESTINATION INTO ALIGNMENT                                         *
  1237. ;                                                                    *
  1238. ;*********************************************************************
  1239. ;  LEFT ROTATE THE FIRST SOURCE  BY SKEW FACTOR                      *
  1240. ;                                                                    *
  1241. ; +-+-+-+-+-+-+-+-+                                                  *
  1242. ; |4|3|2|1|8|7|6|5|                                                  *
  1243. ; +-+-+-+-+-+-+-+-+                                                  *
  1244. ;*********************************************************************
  1245.                PAGE  +
  1246. ;*********************************************************************
  1247. ;                                                                    *
  1248. ;  MASK OFF THE PIXELS TO BE USED FROM THE FIRST SOURCE WORD         *
  1249. ;                                                                    *
  1250. ; +-+-+-+-+-+-+-+-+                                                  *
  1251. ; |0|1|1|1|0|0|0|0| MASKS[SOURCE_LOCAL_SKEW] ROTATED BY SKEW FACTOR  *
  1252. ; +-+-+-+-+-+-+-+-+                                                  *
  1253. ;*********************************************************************
  1254. ;                                                                    *
  1255. ;  LEFT ROTATE THE SECOND SOURCE WORD BY SKEW FACTOR                 *
  1256. ;                                                                    *
  1257. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1258. ; |0|3|2|1|0|0|0|0|          |4|3|2|1|8|7|6|5|    |8|7|6|5|4|3|2|1|  *
  1259. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1260. ;*********************************************************************
  1261. ;                                                                    *
  1262. ;  MASK OFF THE PIXELS TO BE USED FROM SOURCE WORD 2                 *
  1263. ;                                                                    *
  1264. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1265. ; |0|3|2|1|0|0|0|0|          |4|3|2|1|8|7|6|5|    |8|7|6|5|4|3|2|1|  *
  1266. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1267. ;                            +-+-+-+-+-+-+-+-+                       *
  1268. ;                            |0|0|0|0|1|1|1|1| MASKS[SKEW_FACTOR]    *
  1269. ;                            +-+-+-+-+-+-+-+-+                       *
  1270. ;                            +-+-+-+-+-+-+-+-+                       *
  1271. ;                            |0|0|0|0|8|7|6|5|                       *
  1272. ;                            +-+-+-+-+-+-+-+-+                       *
  1273. ;*********************************************************************
  1274. ;                                                                    *
  1275. ;  COMPLEMENT THE MASK AND SAVE THE PIXELS FROM WORD N               *
  1276. ; FOR USE WITH N+1                                                   *
  1277. ;                                                                    *
  1278. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1279. ; |0|3|2|1|0|0|0|0|          |4|3|2|1|8|7|6|5|    |8|7|6|5|4|3|2|1|  *
  1280. ; +-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+    +-+-+-+-+-+-+-+-+  *
  1281. ;                            +-+-+-+-+-+-+-+-+                       *
  1282. ;                            |1|1|1|1|0|0|0|0| NOT MASKS[SKEW_FACTOR]*
  1283. ;                            +-+-+-+-+-+-+-+-+                       *
  1284. ;                            +-+-+-+-+-+-+-+-+                       *
  1285. ;                            |4|3|2|1|0|0|0|0| SAVE FOR NEXT ROUND   *
  1286. ;                            +-+-+-+-+-+-+-+-+                       *
  1287. ;*********************************************************************
  1288. ;                                                                    *
  1289. ;  MERGE SOURCE WORDS 1 AND 2                                        *
  1290. ;                                                                    *
  1291. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1292. ;              |0|3|2|1|8|7|6|5|            |8|7|6|5|4|3|2|1|        *
  1293. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1294. ;*********************************************************************
  1295. ;                                                                    *
  1296. ;  MASK OFF PIXELS TO BE USED FOROM/TO DESTINATION WORD 1            *
  1297. ;                                                                    *
  1298. ;DESTINATION                                                         *
  1299. ;STARTS HERE------+  DEST WORD 1               DEST WORD 2           *
  1300. ;                 V                                                  *
  1301. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1302. ;              |8|7|6|5|4|3|2|1|            |8|7|6|5|4|3|2|1|        *
  1303. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1304. ;              +-+-+-+-+-+-+-+-+                                     *
  1305. ;              |0|1|1|1|1|1|1|1|  MASKS[DEST_LOCAL_SKEW]             *
  1306. ;              +-+-+-+-+-+-+-+-+                                     *
  1307. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1308. ;              |0|7|6|5|4|3|2|1|            |8|7|6|5|4|3|2|1|        *
  1309. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1310. ;*********************************************************************
  1311.                PAGE  +
  1312. ;*********************************************************************
  1313. ;  MASK OFF PIXELS NOT USED FOR MERGE BRFORE WRITING DEST WORD 1     *
  1314. ;                                                                    *
  1315. ;DESTINATION                                                         *
  1316. ;STARTS HERE------+  DEST WORD 1               DEST WORD 2           *
  1317. ;                 V                                                  *
  1318. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1319. ;              |8|7|6|5|4|3|2|1|            |8|7|6|5|4|3|2|1|        *
  1320. ;              +-+-+-+-+-+-+-+-+            +-+-+-+-+-+-+-+-+        *
  1321. ;              +-+-+-+-+-+-+-+-+                                     *
  1322. ;              |1|0|0|0|0|0|0|0|  NOT MASKS[DEST_LOCAL_SKEW]         *
  1323. ;              +-+-+-+-+-+-+-+-+                                     *
  1324. ;              +-+-+-+-+-+-+-+-+                                     *
  1325. ;              |8|0|0|0|0|0|0|0|   SAVE FOR A WHILE                  *
  1326. ;              +-+-+-+-+-+-+-+-+                                     *
  1327. ;*********************************************************************
  1328. ;                                                                    *
  1329. ;  PERFORM THE BITBLT OPERATION ON THE SOURCE AND DESTINATION USING  *
  1330. ; AN OPTIONAL HALFTONE WORD                                          *
  1331. ;                                                                    *
  1332. ;              +-+-+-+-+-+-+-+-+                                     *
  1333. ;              |0|3|2|1|8|7|6|5|  SOURCE WORD                        *
  1334. ;              +-+-+-+-+-+-+-+-+                                     *
  1335. ;              +-+-+-+-+-+-+-+-+                                     *
  1336. ;              |H|H|H|H|H|H|H|H|  HALF-TONE WORD                     *
  1337. ;              +-+-+-+-+-+-+-+-+                                     *
  1338. ;              +-+-+-+-+-+-+-+-+                                     *
  1339. ;              |0|7|6|5|4|3|2|1|  DESTINATION WORD                   *
  1340. ;              +-+-+-+-+-+-+-+-+                                     *
  1341. ;              +-+-+-+-+-+-+-+-+                                     *
  1342. ;              |0|R|R|R|R|R|R|R|  RESULT WORD                        *
  1343. ;              +-+-+-+-+-+-+-+-+                                     *
  1344. ;*********************************************************************
  1345. ;                                                                    *
  1346. ;  MERGE THE PIXELS NOT USED FROM DESTINATION INTO RESULT            *
  1347. ;                                                                    *
  1348. ;              +-+-+-+-+-+-+-+-+                                     *
  1349. ;              |8|0|0|0|0|0|0|0|   SAVE FOR A WHILE                  *
  1350. ;              +-+-+-+-+-+-+-+-+                                     *
  1351. ;              +-+-+-+-+-+-+-+-+                                     *
  1352. ;              |0|R|R|R|R|R|R|R|  RESULT WORD                        *
  1353. ;              +-+-+-+-+-+-+-+-+                                     *
  1354. ;              +-+-+-+-+-+-+-+-+                                     *
  1355. ;              |8|R|R|R|R|R|R|R|  STORE TO DESTINATION               *
  1356. ;              +-+-+-+-+-+-+-+-+                                     *
  1357. ;                                                                    *
  1358. ;*********************************************************************
  1359.                PAGE  +
  1360. ;
  1361. ; FIRST COMPUTE SHIFT DIRECTION AND COUNT
  1362. ;
  1363. ;  GET THE SKEW FACTOR
  1364. ;
  1365.                XOR     BP,BP            ; BP WILL DETERMINE LEFT/RIGHT
  1366.                XOR     DX,DX
  1367.                MOV     AX,SSKEW_LEFT
  1368.                MOV     BX,AX
  1369.                SUB     AX,DSKEW_LEFT
  1370.                CMP     AX,DX
  1371.                JGE     DO_SHIFT
  1372.                NEG     AX
  1373.                DEC     BP               ; NO PRECHARGE, BASE IS LEFT
  1374. DO_SHIFT:
  1375.                MOV     DI,AX      ; USED IF PRECHARGE
  1376. ;
  1377. ; GET DIFFERENCE TIMES BITS PER PIXEL
  1378. ;
  1379.                MOV     CL,BYTE PTR LOG_BITS_PIX
  1380.                SAL     AX,CL       ; COUNT =(SX-DX)*BITS_PIXEL
  1381.                MOV     CX,AX
  1382.                CMP     AL,BYTE PTR BITS_WORD/2
  1383.                JNA       SHORT SAVE_COUNT
  1384. REVERSE1:
  1385. ;
  1386. ; OPPOSITE DIRECTION COUNT =16-OLD_COUNT
  1387. ;
  1388.                MOV     CL,BYTE PTR BITS_WORD
  1389.                SUB     CL,AL
  1390.                NOT     BP         ; CHANGE LEFT TO RIGHT AND VICE VERSA
  1391. SAVE_COUNT:
  1392.                MOV     COUNT,CX
  1393.                TEST    HDIR,WORD PTR FORWARD
  1394.                JE       NORM_DIR
  1395.                NOT     BP         ; IF BACKWARD COPY, REVERSE ROTATE DIR
  1396. NORM_DIR:
  1397.                MOV     DIRECTION,BP
  1398. ;
  1399. ; NOW BUILD MASKS
  1400. ;
  1401.                TEST    PRECHRG,WORD PTR NO_PREC
  1402.                JNE       MASKS_PRECH
  1403.                PAGE
  1404. MASKS_NOP:
  1405. ;
  1406. ; BUILD MASKS FOR NON PRECHARGE OPERAION AND STORE THEM INTO
  1407. ; THE COPY ROUTINE
  1408. ;
  1409.                TEST    HDIR,WORD PTR FORWARD
  1410.                JE        MASKS_FORW1
  1411.                CALL    GET_BMASK         ;BX=INDEX*AX=MASK ON RETURN
  1412.                MOV     SI,OFFSET FIRST_MASK
  1413.                MOV     [SI],AX
  1414.                JMP        SHORT MASK_COM1
  1415. MASKS_FORW1:
  1416.                CALL    GET_MASK         ;BX=INDEX*AX=MASK ON RETURN
  1417.                MOV     SI,OFFSET FIRST_MASK
  1418.                MOV     [SI],AX
  1419. MASK_COM1:
  1420. ;
  1421. ; NO MASK 2 USED, MASK 3 AND 4 SAME AS MASK 1
  1422. ;
  1423.                MOV     SI,OFFSET THIRD_MASK
  1424.                MOV     [SI],AX
  1425.                MOV     SI,OFFSET FOURTH_MASK
  1426.                MOV     [SI],AX
  1427. ;
  1428. ; WRITE IN JUMP CODE OVER LODSW FOR SECOND SOURCE WORD GET
  1429. ;
  1430.                MOV     SI,OFFSET SKIP
  1431.                MOV     AX,[SI]
  1432.                MOV     SI,OFFSET PRECHRG_LOAD
  1433.                MOV     [SI],AX
  1434.                JMP       EPI_MASK
  1435.                PAGE
  1436. MASKS_PRECH:
  1437. ;
  1438. ; BUILD MASKS FOR PRECHARGE OPERAION AND STORE THEM INTO
  1439. ; THE COPY ROUTINE
  1440. ;
  1441.                TEST    HDIR,WORD PTR FORWARD
  1442.                JE        FMASKP
  1443. ;
  1444. ; PRECHARGE MASK BUILD FOR BACKWARD COPY
  1445. ;
  1446.                CALL    GET_BMASK         ;BX=INDEX*AX=MASK ON RETURN
  1447.                MOV     DX,DI      ; ROTATE MASK TO SSKEW-DSKEW*BITS_PIXE
  1448.                MOV     CL,BYTE PTR LOG_BITS_PIX
  1449.                ROL     DX,CL
  1450.                MOV     CX,DX      ; ADJUSTED SHIFT COUNT TO CL
  1451.                ROL     AX,CL
  1452.                MOV     SI,OFFSET FIRST_MASK
  1453.                MOV     [SI],AX
  1454. ;
  1455. ; NOW GET SECOND/FOURTH MASK AND STORE IT
  1456. ;   DI HAS SKEW FACTOR
  1457. ;
  1458.                PUSH    BX
  1459.                MOV     BX,DI
  1460.                CALL    GET_BMASK         ;BX=INDEX*AX=MASK ON RETURN
  1461.                POP     BX
  1462.                MOV     SI,OFFSET SECOND_MASK
  1463.                MOV     [SI],AX
  1464.                MOV     SI,OFFSET FOURTH_MASK
  1465.                MOV     [SI],AX
  1466. ;
  1467. ; SAME FOR THIRD MASK
  1468. ;
  1469.                PUSH    BX
  1470.                MOV     BX,DI
  1471.                DEC     BX
  1472.                CALL    GET_BMASK         ;BX=INDEX*AX=MASK ON RETURN
  1473.                POP     BX
  1474.                MOV     SI,OFFSET THIRD_MASK
  1475.                MOV     [SI],AX
  1476. ;
  1477. ; MAKE SURE LODSW AND IS RESTORED
  1478. ;
  1479.                MOV     SI,OFFSET LOAD_CODE
  1480.                MOV     AL,[SI]
  1481.                MOV     SI,OFFSET PRECHRG_LOAD
  1482.                MOV     [SI],AL
  1483.                JMP     EPI_MASK
  1484.                PAGE
  1485. ;
  1486. ; BUILD PRECHARGE MASKS FOR FORWARD COPY
  1487. ;
  1488. FMASKP:
  1489.                CALL    GET_MASK         ;BX=INDEX*AX=MASK ON RETURN
  1490.                MOV     DX,DI      ; ROTATE MASK TO SSKEW-DSKEW*BITS_PIXE
  1491.                MOV     CL,BYTE PTR LOG_BITS_PIX
  1492.                ROL     DX,CL
  1493.                MOV     CX,DX      ; ADJUSTED SHIFT COUNT TO CL
  1494.                ROL     AX,CL
  1495.                MOV     SI,OFFSET FIRST_MASK
  1496.                MOV     [SI],AX
  1497. ;
  1498. ; NOW GET SECOND/FOURTH MASK AND STORE IT
  1499. ;   DI HAS SKEW FACTOR
  1500. ;
  1501.                PUSH    BX
  1502.                MOV     BX,DI
  1503.                CALL    GET_MASK         ;BX=INDEX*AX=MASK ON RETURN
  1504.                POP     BX
  1505.                MOV     SI,OFFSET SECOND_MASK
  1506.                MOV     [SI],AX
  1507.                MOV     SI,OFFSET FOURTH_MASK
  1508.                MOV     [SI],AX
  1509. ;
  1510. ; SAME FOR THIRD MASK
  1511. ;
  1512.                PUSH    BX
  1513.                MOV     BX,DI
  1514.                INC     BX
  1515.                CALL    GET_MASK         ;BX=INDEX*AX=MASK ON RETURN
  1516.                POP     BX
  1517.                MOV     SI,OFFSET THIRD_MASK
  1518.                MOV     [SI],AX
  1519. ;
  1520. ; MAKE SURE LODSW AND IS RESTORED
  1521. ;
  1522.                MOV     SI,OFFSET LOAD_CODE
  1523.                MOV     AL,[SI]
  1524.                MOV     SI,OFFSET PRECHRG_LOAD
  1525.                MOV     [SI],AL
  1526.                PAGE
  1527. EPI_MASK:
  1528. ;
  1529. ; BUILD EPILOGUE MASK
  1530. ;
  1531.                MOV     DI,DSKEW_RIGHT
  1532. ;
  1533. ; RIGHT SKEW IS THE NUMBER OF PIXELS TO MODIFY
  1534. ; SO JUST USE AS INDEX INTO BACK MASKS
  1535. ;
  1536.                PUSH    BX
  1537.                MOV     BX,DI
  1538.                CALL    GET_MASK         ;BX=INDEX*AX=MASK ON RETURN
  1539.                POP     BX
  1540.                MOV     WORD PTR FIFTH_MASK,AX
  1541.                PAGE
  1542. BUILD_ROTS:
  1543. ; WRITE IN ROTATE CODES
  1544. ;
  1545. ; FIRST GET COUNT
  1546. ;
  1547.                MOV     CX,COUNT
  1548.                CMP     BYTE PTR DIRECTION,BYTE PTR 0
  1549.                JE        RIGHT_ROT
  1550.                MOV     SI,OFFSET ROTATE_LEFT
  1551.                JMP       SHORT WRITE_ROT1
  1552. RIGHT_ROT:
  1553.                MOV     SI,OFFSET ROTATE_RIGHT
  1554. WRITE_ROT1:
  1555.                ADD     SI,CX      ; FORM INDEX INTO ROTATE CODE
  1556.                MOV     AX,CS
  1557.                MOV     ES,AX      ; SET DESTINATION SEG=CODE
  1558.                MOV     AX,SI      ; SAVE INDEX INTO ROTATE CODE
  1559.                MOV     DI,OFFSET FIRST_ROT  ; SET DESTINATION INDEX
  1560.                STD                ; SET DIRECTION FORWARD
  1561.                MOVSW              ; COPY 1ST  INSTRUCTION
  1562.                MOVSW              ; COPY 2OND INSTRUCTION
  1563.                MOVSW              ; COPY 3RD  INSTRUCTION
  1564.                MOVSW              ; COPY 4TH  INSTRUCTION
  1565.                MOVSW              ; COPY 5TH  INSTRUCTION
  1566.                MOVSW              ; COPY 6TH  INSTRUCTION
  1567.                MOVSW              ; COPY 7TH  INSTRUCTION
  1568.                MOVSW              ; COPY 8TH  INSTRUCTION
  1569.                MOV     DI,OFFSET SECOND_ROT  ; SET DEST TO INNER LOOP
  1570.                MOV     SI,AX      ; RESET SOURCE TO TEMPLATE
  1571.                TEST    PRECHRG,WORD PTR NO_PREC
  1572.                JNE         DO_FIRST
  1573.                INC     SI         ;IF NO PRECHARGE DON'T OVER WRITE
  1574.                INC     SI         ; THE JUMP CODE
  1575.                JMP      SHORT SKIP_FIRST
  1576. DO_FIRST:
  1577.                MOVSW              ; COPY 1ST  INSTRUCTION
  1578. SKIP_FIRST:
  1579.                MOVSW              ; COPY 2OND INSTRUCTION
  1580.                MOVSW              ; COPY 3RD  INSTRUCTION
  1581.                MOVSW              ; COPY 4TH  INSTRUCTION
  1582.                MOVSW              ; COPY 5TH  INSTRUCTION
  1583.                MOVSW              ; COPY 6TH  INSTRUCTION
  1584.                MOVSW              ; COPY 7TH  INSTRUCTION
  1585.                MOVSW              ; COPY 8TH  INSTRUCTION
  1586.                MOV     DI,OFFSET THIRD_ROT   ; SET DEST TO INNER LOOP
  1587.                MOV     SI,AX      ; RESET SOURCE TO TEMPLATE
  1588.                MOVSW              ; COPY 1ST  INSTRUCTION
  1589.                MOVSW              ; COPY 2OND INSTRUCTION
  1590.                MOVSW              ; COPY 3RD  INSTRUCTION
  1591.                MOVSW              ; COPY 4TH  INSTRUCTION
  1592.                MOVSW              ; COPY 5TH  INSTRUCTION
  1593.                MOVSW              ; COPY 6TH  INSTRUCTION
  1594.                MOVSW              ; COPY 7TH  INSTRUCTION
  1595.                MOVSW              ; COPY 8TH  INSTRUCTION
  1596.                PAGE
  1597.                MOV     DI,OFFSET FOURTH_ROT ; SET DEST TO EPILOG
  1598.                MOV     SI,AX      ; RESET SOURCE TO TEMPLATE
  1599.                MOVSW              ; COPY 1ST  INSTRUCTION
  1600.                MOVSW              ; COPY 2OND INSTRUCTION
  1601.                MOVSW              ; COPY 3RD  INSTRUCTION
  1602.                MOVSW              ; COPY 4TH  INSTRUCTION
  1603.                MOVSW              ; COPY 5TH  INSTRUCTION
  1604.                MOVSW              ; COPY 6TH  INSTRUCTION
  1605.                MOVSW              ; COPY 7TH  INSTRUCTION
  1606.                MOVSW              ; COPY 8TH  INSTRUCTION
  1607. ;
  1608. ;*********************************************************************
  1609. ;                                                                    *
  1610. ;    WRITE THE CODE TO PERFORM THE OPERATION REQUESTED INTO          *
  1611. ;  THE PROLOG,EPILOG, AND INNER LOOP CODE OF THE HORZ COPY           *
  1612. ;                                                                    *
  1613. ;   OPN_CODE*8 IS THE INDEX INTO THE TEMPLATE TABLES                 *
  1614. ;                                                                    *
  1615. ;   ASSUMES DS,ES POINT TO CODE SEG                                  *
  1616. ;                                                                    *
  1617. ;*********************************************************************
  1618. ;
  1619.                MOV    AL,OPN_CODE ; GET BITBLT OPERATION CODE
  1620.                XOR    AH,AH       ; CLEAR UPPER
  1621.                SAL    AX,1        ; CODE TIMES 8
  1622.                SAL    AX,1
  1623.                SAL    AX,1
  1624.                MOV    BP,AX                  ; SAVE OFFSET INTO BP
  1625. ;
  1626. ; FIRST DO INNER LOOP CODE
  1627. ;
  1628.                CMP    HDIR,0
  1629.                JNE       BACKWARD_UN
  1630.                MOV    SI,OFFSET OPN_LOOP_F ; LOCATION OF TEMPLATE
  1631.                JMP       SHORT UN_IN_CMN     ; COMMON INNER COPY
  1632. BACKWARD_UN:
  1633.                MOV    SI,OFFSET OPN_LOOP_B ; LOCATION OF TEMPLATE
  1634. UN_IN_CMN:
  1635.                ADD    SI,AX                  ; ADD IN INDEX
  1636.                MOV    DI,OFFSET LOOP_OPN   ; WHERE TO STORE TEMPLATE
  1637.                STD                           ; SET DIRECTION FORWARD
  1638.                MOVSW              ; FIRST 2 BYTES OF OPERATION STREAM
  1639.                MOVSW              ; BYTES 3-4
  1640.                MOVSW              ; BYTES 5-6
  1641.                MOVSW              ; BYTES 7-8
  1642. ;
  1643. ; THEN DO PROLOGUE OPERATION CODE
  1644. ;
  1645.                MOV    SI,OFFSET OPN_PRO_EPI ; LOCATION OF TEMPLATE
  1646.                ADD    SI,BP                   ; ADD IN INDEX
  1647.                MOV    BP,SI                   ; SAVE FOR 2OND COPY
  1648.                MOV    DI,OFFSET PROLOG_OPN  ; WHERE TO STORE TEMPLATE
  1649.                MOVSW              ; FIRST 2 BYTES OF OPERATION STREAM
  1650.                MOVSW              ; BYTES 3-4
  1651.                MOVSW              ; BYTES 5-6
  1652.                MOVSW              ; BYTES 7-8
  1653. ;
  1654. ; LASTLY DO EPILOGUE OPERATION CODE
  1655. ;
  1656.                MOV     SI,BP                   ; RESTORE TEMPLATE ORG
  1657.                MOV     DI,OFFSET EPILOG_OPN  ; WHERE TO STORE TEMPLATE
  1658.                MOVSW              ; FIRST 2 BYTES OF OPERATION STREAM
  1659.                MOVSW              ; BYTES 3-4
  1660.                MOVSW              ; BYTES 5-6
  1661.                MOVSW              ; BYTES 7-8
  1662.                MOV   SAVE_SP,SP
  1663.                MOV   SAVE_SS,SS
  1664.                .XLIST
  1665.                SUBTTL    UNALIGNED COPY BITS ROUTINE-----VERTICAL LOOP
  1666.                .LIST
  1667.                PAGE  +
  1668. ;
  1669. ;
  1670. ;*********************************************************************
  1671. ;                                                                    *
  1672. ;  MAIN LOOP OF COPY BITS FOR UN-ALIGNED DATA                        *
  1673. ;                                                                    *
  1674. ;                                                                    *
  1675. ;                                                                    *
  1676. ;                                                                    *
  1677. ;*********************************************************************
  1678. COPYBITS_UN:
  1679.                XOR   AX,AX
  1680.                CMP   AX,HDIR
  1681.                JNE     VERT_BACK_UN
  1682.                STD                ; SET DIRECTION FORWARD, DELTA POS
  1683.                JMP     SHORT V_LOADP_UN
  1684. VERT_BACK_UN:
  1685.                CLD                ; SET DIRECTION BACKWARD, DELTA NEG
  1686. V_LOADP_UN:
  1687.                LES   SI,CURR_PTR_S  ; SET UP ALL PTRS XCEPT DS
  1688.                MOV   AX,ES
  1689.                LES   DI,CURR_PTR_D
  1690.                CLI                ; DISABLE INTERRUPTS
  1691.                MOV   SP,AX
  1692.                PAGE
  1693. ;
  1694. ;*********************************************************************
  1695. ;                                                                    *
  1696. ;    INNER PART OF VERT LOOP. THIS CODE RUNS BLIND BECAUSE THE       *
  1697. ; MAIN BITBLT CODE DETERMINED HOW MANY SCAN LINES CAN BE RUN         *
  1698. ; BEFORE THE VIDEO MUST BE TURNED ON. (IE HOW MANY WORDS CAN BE      *
  1699. ; COPIED IN 1/60 SEC)                                                *
  1700. ;                                                                    *
  1701. ;*********************************************************************
  1702. DUMMY          EQU     0
  1703. SELF_MASK1     EQU     DUMMY
  1704. SELF_MASK2     EQU     DUMMY
  1705. SELF_MASK3     EQU     DUMMY
  1706. SELF_MASK4     EQU     DUMMY
  1707. SELF_MASK5     EQU     DUMMY
  1708. SELF_HWC       EQU     DUMMY
  1709. H_MASK_END     EQU     DUMMY
  1710. VERT_LOOP:
  1711.                XOR   BX,BX
  1712.                MOV   BL,HTONE_INDX      ; GET HALF TONE INDEX
  1713.                AND   BL,HTONE_MOD       ; USE MODULO ARITHMETIC
  1714.                MOV   BP,HTONE_VEC[BX]   ; GET HALF TONE VALUE
  1715.                INC   BL                 ; TO NEXT HALF TONE
  1716.                MOV   HTONE_INDX,BL
  1717.                MOV   AX,SP
  1718.                MOV   DS,AX              ; DS ADDRESSIBILTY TO SOURCE
  1719.                .XLIST
  1720.                SUBTTL    UNALIGNED HORIZONTAL COPY ROUTINE---PROLOGUE
  1721.                .LIST
  1722.                PAGE  +
  1723. ;
  1724. ;*********************************************************************
  1725. ;                                                                    *
  1726. ;  ASSUMES:  DS,SI POINT TO SOURCE WORD                              *
  1727. ;            ES,DI POINT TO DEST   WORD                              *
  1728. ;            BP HAS HALFTONE MASK                                    *
  1729. ;                                                                    *
  1730. ; DESTROYS: AX,BX,CX,DX,SS,SI,DI,SP                                  *
  1731. ;                                                                    *
  1732. ;*********************************************************************
  1733. ; HORIZONTAL  COPY LOOP OF BITBLIT. A GREAT DEAL OF THIS CODE        *
  1734. ; IS MODIFIED IN THE MAIN SETUP PORTION OF BITBLT. THIS              *
  1735. ; MAY SEEM UGLY (AND IT IS), BUT THE TIME SAVINGS IT                 *
  1736. ; ACHIEVES IS WELL WORTH THE UGLINESS. THIS PARTICULAR               *
  1737. ; COPY LOOP IS EXECUTED ONLY IS THOSE CASES WHERE THE                *
  1738. ; OFFSET OF PIXELS WITHIN A WORD IS NOT THE SAME IN THE              *
  1739. ; SOURCE BITMAP AND THE DESTINATION BITMAP. THIS DOES NOT INCLUDE    *
  1740. ; THE FOLLOWING CASES:                                               *
  1741. ;   CONSTANT TO DESTINATION IE, CLEAR, ALLONES, OR HALFTONE/COLOR    *
  1742. ;*********************************************************************
  1743. ;
  1744. ;*********************************************************************
  1745. ;                                                                    *
  1746. ;  SETUP CODE FIRST. SETUP FOR FIRST PARTIAL WORD COPY               *
  1747. ;                                                                    *
  1748. ;*********************************************************************
  1749. ;
  1750. ; GET THE FIRST SOURCE WORD AND ROTATE IT INTO POSITION
  1751. ;
  1752.  
  1753.                LODSW              ; AX<-- DS:[SI],SI<-- SI+/-2
  1754.                EVEN
  1755. H_SELF1:
  1756.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1757.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1758.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1759.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1760.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1761.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1762.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1763.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1764.                PAGE
  1765. ;
  1766. ; NOW MASK OFF THE STUFF NEEDED FROM SOURCE WORD 1
  1767. ;
  1768.                NOP                ; PUT OPERAND ON EVEN
  1769. H_SELF2:
  1770.                MOV    CX,WORD PTR SELF_MASK1
  1771.                MOV    SS,AX       ; WE DO IT THIS WAY BECAUSE
  1772.                AND    AX,CX       ; BITBLT MAIN MAY DECIDE TO USE
  1773.                MOV    BX,AX       ; ONLY ONE WORD (NO PRECHARGE)
  1774. ;
  1775. ; HAD TO PUT THE JUMP IN HERE BECAUSE MASM WILL NOT ALLOW
  1776. ; AN ORG TO A RELATIVE ADDRESS
  1777. ;
  1778. ; THE NEXT 3 BYTES MAY BE ONE OF TWO INSTRUCTION STREAMS
  1779. ;  THE JUMP (CODED INLINE)
  1780. ;   A LODSW AND ROR(ROL),1
  1781. ;
  1782.                NOP                ; PUT FIRST BYTE OF JUMP ON ODD
  1783. H_SELF3:                          ; GET SOURCE WORD 2 AND ROTATE
  1784. SKIP_CODE:
  1785.                JMP      SHORT NO_PRECHARG  ; BITBLT MAIN WILL REWRITE
  1786.                NOP
  1787.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1788.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1789.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1790.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1791.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1792.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1793.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1794.                MOV    SS,AX       ; WORD 2 NEEDED TO PRECHARGE LOOP
  1795.                NOP                ; PUT OPERAND ON EVEN
  1796. H_SELF4:
  1797.                MOV    CX,WORD PTR SELF_MASK2
  1798.                AND    AX,CX       ; MASK PIXELS IN SOURCE WORD 2
  1799.                OR     BX,AX       ; SWORD1|SWORD2 NOW ALIGNED WITH DEST
  1800. NO_PRECHARG:
  1801.                AND    BX,BP       ; AND IN HALFTONE/COLOR
  1802.                MOV    AX,ES:[DI]  ; GET DESTINATION WORD
  1803. H_SELF5:
  1804.                MOV    CX,WORD PTR SELF_MASK3
  1805.                MOV    DX,AX       ; SPLIT DEST WORD INTO 2 PARTS
  1806.                AND    AX,CX       ;  1-THE PART TO BE MODIFIED
  1807.                NOT    CX
  1808.                AND    DX,CX       ; 2- THE PART TO NOT MODIFY
  1809. H_SELF7:
  1810.                NOT    AX          ; BITBLT WILL REWRITE \
  1811.                NOT    BX          ; BITBLT WILL REWRITE  * OPERATION
  1812.                OR     AX,BX       ; BITBLT WILL REWRITE /
  1813.                NOP                ; BITBLT WILL REWRITE
  1814.                NOP                ; BITBLT WILL REWRITE
  1815.                OR     AX,DX       ; MERGE DEST TOGETHER
  1816.                STOSW              ; RESULT OF MERGE-->ES:[DI], DI-->DI+2
  1817.                XOR    CX,CX       ; PUT H WORD COUNT INTO CX
  1818. H_SELF8:
  1819.                MOV    CX,WORD PTR 0   ; NUMBER OF WORDS WRITTEN HERE
  1820. ;
  1821. ; HWC=N-1 IF NO PRECHARGE N-2 IF PRECHARGE
  1822. ;
  1823.                AND    CL,CL
  1824.                JZ     H_TERMIN
  1825. H_SELF9:
  1826.                MOV    BX,WORD PTR SELF_MASK4 ; MASK TO BE USED FOR LOOP R
  1827.                .XLIST
  1828.                SUBTTL    UNALIGNED HORIZONTAL COPY ROUTINE---INNER LOOP
  1829.                .LIST
  1830.                PAGE  +
  1831. ;*********************************************************************
  1832. ;                                                                    *
  1833. ;  WAY WAY INNER LOOP OF BITBLT (EXECUTED MANY MANY TIMES)           *
  1834. ;                                                                    *
  1835. ;*********************************************************************
  1836.                EVEN
  1837.                NOP                ; MAKE LODSW ODD REST EVEN
  1838. HORZW_LOOP:                       ; ON ENTEY DX=PREV PART
  1839.                LODSW
  1840. H_SELF10:      ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1841.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1842.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1843.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1844.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1845.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1846.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1847.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1848.                MOV    SS,AX       ; SAVE THIS WORD
  1849.                AND    AX,BX       ; MASK OFF NUMBER OF BITS THIS WORD
  1850.                NOT    BX          ; COMPLEMENT MASK FOR PREV WORD
  1851.                AND    DX,BX       ; MASK OFF NUMBER OF BITS PREV WORD
  1852.                NOT    BX          ; RESTORE MASK
  1853.                OR     AX,DX       ; AX NOW HAS WORD FOR DESTINATION
  1854.                AND    AX,BP       ; AND IN HALFTONE MASK
  1855. H_SELF11:
  1856.                NOP   ; THIS BLOCK REWRITTEN BY BITBLT MAIN
  1857.                NOP   ;  SAVES HAVING TO WRITE 16 LOOPS
  1858.                NOP   ;  EACH WITH ITS OWN MERGE FUNCTION
  1859.                NOP   ;
  1860.                NOP   ;  DOING A VECTOR JUMP AND A EXIT JUMP
  1861.                NOP   ;  TAKES WAY TOO MUCH TIME  APPROX 31 CLOCKS
  1862.                NOP   ;
  1863.                NOP   ;
  1864.                MOV    DX,SS       ; SETUP DX FOR NEXT
  1865.                LOOP   HORZW_LOOP
  1866.                .XLIST
  1867.                SUBTTL    UNALIGNED HORIZONTAL COPY ROUTINE---EPILOGUE
  1868.                .LIST
  1869.                PAGE  +
  1870. ;
  1871. ;*********************************************************************
  1872. ;                                                                    *
  1873. ; NOW DO LAST WORD. THIS IS THE SAME A LOOP, JUST MASK OFF           *
  1874. ; SOURCE ONE LAST TIME SO WE DON'T MOVE BEYOND THE DESTINATION IN X  *
  1875. ;                                                                    *
  1876. ;                                                                    *
  1877. ;*********************************************************************
  1878. ;
  1879. H_TERMIN:
  1880.                LODSW
  1881.                EVEN
  1882. H_SELF12:
  1883.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1884.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1885.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1886.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1887.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1888.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1889.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1890.                ROR    AX,1        ; BITBLT MAIN WILL RE-WRITE
  1891.                AND    AX,BX       ; MASK OFF NUMBER OF BITS THIS WORD
  1892.                NOT    BX          ; COMPLEMENT MASK FOR PREV WORD
  1893.                AND    DX,BX       ; MASK OFF NUMBER OF BITS PREV WORD
  1894.                OR     DX,AX       ; DX NOW HAS WORD FOR DESTINATION
  1895.                AND    DX,BP       ; AND IN HALFTONE MASK
  1896.                NOP                ; PUT OPERAND ON EVEN
  1897. H_SELF13:
  1898.                MOV    CX,WORD PTR H_MASK_END
  1899.                MOV    BX,DX       ; PUT SOURCE INTO BX SO REWRITE'S OK
  1900.                AND    BX,CX
  1901.                MOV    AX,ES:[DI]
  1902.                NOP                ; PUT REST EVEN
  1903.                MOV    DX,AX       ; SPLIT DEST WORD INTO 2 PARTS
  1904.                AND    AX,CX       ;  1- THE PART TO BE MODIFIED
  1905.                NOT    CX          ; MASK OFF STUFF TO KEEP AT DEST
  1906.                AND    DX,CX       ;  2- THE INVARIANT PART
  1907. ;
  1908. ;  HERE AX HAS WORD TO BE OP'D FROM DEST AND BX AND SOURCE TO OP
  1909. ;
  1910. H_SELF14:
  1911.                NOT    BX ; THIS BLOCK REWRITTEN BY BITBLT MAIN
  1912.                NOT    AX ;  SAVES HAVING TO WRITE 16 LOOPS
  1913.                OR     AX,BX   ;  EACH WITH ITS OWN MERGE FUNCTION
  1914.                OR     AX,DX       ; MERGE DEST PARTS TOGETHER
  1915.                STOSW
  1916.                .XLIST
  1917.                SUBTTL    BOTTOM PART OF VERTICAL LOOP
  1918.                .LIST
  1919.                PAGE  +
  1920. ;
  1921. ;*********************************************************************
  1922. ;                                                                    *
  1923. ;  TERMINATING PORTION OF VERT LOOP. CURRENT SCAN LINE IS COMPLETE   *
  1924. ;                                                                    *
  1925. ;*********************************************************************
  1926.                MOV   AX,DS            ; RESTORE ADDRESSIBILTY TO DATA
  1927.                MOV   SP,AX            ; SAVE DS IN SP
  1928.                MOV   AX,CS
  1929.                MOV   DS,AX
  1930.                ADD   SI,DELTA_S       ; ADJUST POINTER FOR SOURCE
  1931.                ADD   DI,DELTA_D       ; ADJUST POINTER FOR DESTINATION
  1932.                DEC   V_WORD_CNT       ; DONE YET?
  1933.                JZ    EXIT_V_UN        ; YES DO ANOTHER V LOOP
  1934.                JMP     VERT_LOOP        ; NO, DO ANOTHER SCAN LINE
  1935. EXIT_V_UN:
  1936.                MOV    SS,SAVE_SS
  1937.                MOV    SP,SAVE_SP
  1938.                STI                    ; INTERRUPTS OFF LONG ENOUGH
  1939.                RET
  1940.                .XLIST
  1941.                SUBTTL    UNALIGNED HORIZ COPY SELF MODIFY EQUATES
  1942.                .LIST
  1943.                PAGE  +
  1944. ;
  1945. ;*********************************************************************
  1946. ;                                                                    *
  1947. ;      THE FOLLOWING ARE EQUATES INTO THE UGLY HORIZONTAL CODE       *
  1948. ; TO LOCATE THE CODE TO MODIFY                                       *
  1949. ;                                                                    *
  1950. ;*********************************************************************
  1951. ;
  1952. FIRST_ROT      EQU           H_SELF1   ; PROLOGUE 1ST ROTATE
  1953. PRECHRG_LOAD   EQU           H_SELF3   ; PRECHARGE LOAD
  1954. SECOND_ROT     EQU           H_SELF3+1 ; PROLOGUE 2OND ROTATE
  1955. THIRD_ROT      EQU           H_SELF10  ; INNER LOOP ROTATE
  1956. FOURTH_ROT     EQU           H_SELF12  ; EPILOGUE ROTATE
  1957. FIRST_MASK     EQU           H_SELF2+1 ; WHERE TO STORE FIRST MASK
  1958. SECOND_MASK    EQU           H_SELF4+1 ; WHERE TO STORE SECOND MASK
  1959. THIRD_MASK     EQU           H_SELF5+1
  1960. FOURTH_MASK    EQU           H_SELF9+1
  1961. FIFTH_MASK     EQU           H_SELF13+1 ; EPILOGUE MASK
  1962. H_WORD_COUNT   EQU           H_SELF8+1  ; WHERE TO STORE THE H_COUNT
  1963. PROLOG_OPN     EQU           H_SELF7   ;WHERE TO WRITE THE OPERATION COD
  1964. LOOP_OPN       EQU           H_SELF11
  1965. EPILOG_OPN     EQU           H_SELF14
  1966. COPY_NALIGN    ENDP
  1967.                .XLIST
  1968.                SUBTTL    ALIGNED HORIZONTAL COPY ROUTINE
  1969.                .LIST
  1970.                PAGE  +
  1971. COPY_ALIGN     PROC  NEAR
  1972.                MOV   SAVE_SS,SS   ; SAVE SS
  1973.                MOV   SAVE_SP,SP   ; SAVE SP
  1974. ;
  1975. ;*********************************************************************
  1976. ;                                                                    *
  1977. ;        GET MASKS FOR START AND END IN ALIGNED COPY                 *
  1978. ;                                                                    *
  1979. ;*********************************************************************
  1980. ;
  1981.                XOR   AX,AX             ; CHECK IF FORWARD/BACKWARD COPY
  1982.                CMP   AX,HDIR
  1983.                JNE   BACKMASK_AL
  1984.                MOV   BX,SSKEW_LEFT     ; FORWARD COPY. GET SOURCE SKEW
  1985.                XOR   BH,BH
  1986.                CALL  GET_MASK
  1987.                MOV   ALIGN_PRMASK,AX   ; SAVE PROLOGUE MASK
  1988.                MOV   BX,SSKEW_RIGHT    ; GET SKEW AT RIGHT SIDE
  1989.                XOR   BH,BH             ; USE AS INDEX FOR EPILOGUE MASK
  1990.                CALL  GET_BMASK
  1991.                MOV   ALIGN_EPMASK,AX
  1992.                JMP     SHORT COPYBITS_AL
  1993. BACKMASK_AL:
  1994.                MOV   BX,SSKEW_LEFT     ; IF BACKWARD CHK_OVLAP HAS
  1995.                XOR   BH,BH             ; SWAPPED LEFT AND RIGHT
  1996.                CALL  GET_BMASK
  1997.                NOT   AX
  1998.                MOV   ALIGN_PRMASK,AX
  1999.                MOV   BX,SSKEW_RIGHT
  2000.                XOR   BH,BH
  2001.                CALL  GET_MASK
  2002.                MOV   ALIGN_EPMASK,AX
  2003.                PAGE
  2004. ;
  2005. ;*********************************************************************
  2006. ;                                                                    *
  2007. ; COPY IN OPERATION CODE                                             *
  2008. ;                                                                    *
  2009. ;*********************************************************************
  2010. ;
  2011.                XOR   BX,BX                 ; CLEAR BX
  2012.                MOV   BL,OPN_CODE           ; GET INDEX TO OPERATION
  2013.                SAL   BX,1                  ; TEMPLATES TIMES 8
  2014.                SAL   BX,1
  2015.                SAL   BX,1
  2016.                MOV   SI,OFFSET OPN_PRO_EPI ; GET ADDRESS FOR TEMPLATE
  2017.                ADD   SI,BX                 ; ADD IN INDEX
  2018.                MOV   BP,SI                 ; SAVE IT IN BP
  2019.                MOV   DI,OFFSET ALIGN_PROP  ; GET TARGET FOR 1ST COPY
  2020.                MOV   AX,CS                 ; SET UP ES FOR CS
  2021.                MOV   ES,AX                 ; (DS ALREADY IS THERE)
  2022.                STD                         ; FORWARD COPY
  2023.                MOVSW                       ;
  2024.                MOVSW                       ;  COPY OPERATION CODE
  2025.                MOVSW
  2026.                MOVSW
  2027.                MOV   SI,BP                 ; BACK TO START OF TEMPLATE
  2028.                MOV   DI,OFFSET ALIGN_INOP  ; NEW TARGET
  2029.                MOVSW
  2030.                MOVSW                       ;  COPY OPERATION CODE
  2031.                MOVSW
  2032.                MOVSW
  2033.                MOV   SI,BP                 ; BACK TO START OF TEMPLATE
  2034.                MOV   DI,OFFSET ALIGN_INOP  ; NEW TARGET
  2035.                MOVSW
  2036.                MOVSW                       ;  COPY OPERATION CODE
  2037.                MOVSW
  2038.                MOVSW
  2039.                PAGE
  2040. ;
  2041. ;*********************************************************************
  2042. ;                                                                    *
  2043. ; COPY BITS FOR THOSE CASES WHERE THE DESTINATION AND SOURCE         *
  2044. ; HAPPEN TO BE ALIGNED                                               *
  2045. ;                                                                    *
  2046. ;*********************************************************************
  2047. ;
  2048. COPYBITS_AL:
  2049.                XOR   AX,AX
  2050.                CMP   AX,HDIR
  2051.                JB     VERT_BACK_AL
  2052.                STD                    ; FORWARD COPY, DET DIRECTION
  2053.                JMP    SHORT V_LOADP_AL
  2054. VERT_BACK_AL:
  2055.                CLD                    ; BACKWARD COPY, CLEAR DIRECTION
  2056. V_LOADP_AL:
  2057.                LES   SI,CURR_PTR_S  ; LOAD SOURCE AND DEST POINTERS
  2058.                MOV   AX,ES
  2059.                LES   DI,CURR_PTR_D
  2060.                CLI                ; DISABLE INTERRUPTS
  2061.                MOV   SS,AX
  2062.                PAGE
  2063. ALIGN_VERT:
  2064.                XOR   BX,BX
  2065.                MOV   BL,HTONE_INDX   ; GET THE HALFTONE WORD
  2066.                AND   BL,HTONE_MOD    ; FOR THIS SCAN LINE
  2067.                MOV   BP,HTONE_VEC[BX]
  2068.                INC   BX
  2069.                MOV   HTONE_INDX,BL
  2070.                MOV   AX,SS
  2071.                MOV   DS,AX
  2072.                PAGE
  2073. ;*********************************************************************
  2074. ;                                                                    *
  2075. ;    ALIGNED HORIZONTAL COPY ROUTINE                                 *
  2076. ;                                                                    *
  2077. ;                                                                    *
  2078. ;    ASSUMES  DS,SI==>SOURCE  BITMAP                                 *
  2079. ;             ES,DI==>DEST    BITMAP                                 *
  2080. ;              BP = HALFTONE MASK                                    *
  2081. ;                                                                    *
  2082. ;                                                                    *
  2083. ;*********************************************************************
  2084. ;
  2085. ;
  2086. ; PROLOGUE OPERATION
  2087. ;
  2088.                LODSW              ; GET SOURCE 1ST WORD
  2089.                MOV   DX,CS:ALIGN_PRMASK
  2090.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2091.                AND   AX,BP        ; PUT IN HALF TONE
  2092.                MOV   BX,ES:[DI]   ; GET DESTINATION 1ST WORD
  2093.                MOV   CX,BX        ; PUT PORTION OF DEST NOT TO BE
  2094.                NOT   DX           ; MODIFIED INTO CX
  2095.                AND   CX,DX
  2096.                NOT   DX           ; BRING BACK MASK
  2097.                AND   BX,DX        ; MASK OFF DATA TO BE MODIFIED
  2098.                EVEN
  2099. ALIGN_PROP:
  2100.                NOP                ; THESE 8 BYTES WILL BE REWRITTEN
  2101.                NOP                ; WITH THE APPROPRIATE OPERATION
  2102.                NOP
  2103.                NOP
  2104.                NOP
  2105.                NOP
  2106.                NOP
  2107.                NOP
  2108.                OR    AX,CX        ; MERGE MODIFIED WITH CONSTANT
  2109.                STOSW              ; PUT DESTINATION BACK
  2110.                MOV   CX,CS:NWORDS
  2111.                PAGE
  2112. ALIGN_INNER:
  2113.                LODSW              ; GET NEXT SOURCE WORD
  2114.                MOV   BX,ES:[DI]   ; GET NEXT DEST WORD
  2115.                AND   AX,BP        ; AND IN HALFTONE
  2116.                EVEN
  2117. ALIGN_INOP:
  2118.                NOP                ; OPERATION WILL BE WRITTEN IN
  2119.                NOP                ;
  2120.                NOP                ;
  2121.                NOP                ;
  2122.                NOP                ;
  2123.                NOP                ;
  2124.                NOP                ;
  2125.                NOP                ; THESE 8 BYTES
  2126.                LOOP    ALIGN_INNER
  2127.                PAGE
  2128. ;
  2129. ; EPILOG OPERATION
  2130. ;
  2131.                LODSW              ; GET SOURCE 1ST WORD
  2132.                MOV   DX,CS:ALIGN_EPMASK
  2133.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2134.                AND   AX,BP        ; PUT IN HALF TONE
  2135.                MOV   BX,ES:[DI]   ; GET DESTINATION 1ST WORD
  2136.                MOV   CX,BX        ; PUT PORTION OF DEST NOT TO BE
  2137.                NOT   DX           ; MODIFIED INTO CX
  2138.                AND   CX,DX
  2139.                NOT   DX           ; BRING BACK MASK
  2140.                AND   BX,DX        ; MASK OFF DATA TO BE MODIFIED
  2141.                EVEN
  2142. ALIGN_EPOP:
  2143.                NOP                ; THESE 8 BYTES WILL BE REWRITTEN
  2144.                NOP                ; WITH THE APPROPRIATE OPERATION
  2145.                NOP
  2146.                NOP
  2147.                NOP
  2148.                NOP
  2149.                NOP
  2150.                NOP
  2151.                OR    AX,CX        ; MERGE MODIFIED WITH CONSTANT
  2152.                STOSW              ; PUT DESTINATION BACK
  2153.                PAGE
  2154. ;
  2155. ; LOWER PORTION OF VERT LOOP
  2156. ;
  2157.                MOV   AX,DS
  2158.                MOV   SS,AX        ; SAVE OLD SEG TO SOURCE
  2159.                MOV   AX,CS
  2160.                MOV   DS,AX        ; RESTORE ADDRESSIBILTY TO CS
  2161.                ADD   SI,DELTA_S
  2162.                ADD   DI,DELTA_D
  2163.                DEC   V_WORD_CNT   ; ANOTHER H SCAN
  2164.                JZ     DONE_VERT    ; YES, GO DO IT
  2165.                JMP    ALIGN_VERT
  2166. DONE_VERT:
  2167.                MOV   SS,SAVE_SS
  2168.                MOV   SP,SAVE_SP
  2169.                STI                ; ENABLE INTERRUPTS
  2170.                RET
  2171. COPY_ALIGN     ENDP
  2172.                .XLIST
  2173.                SUBTTL    FAST COPY ROUTINE----MAIN PROC
  2174.                .LIST
  2175.                PAGE  +
  2176. COPY_FAST      PROC  NEAR
  2177.                MOV   SAVE_SS,SS   ; SAVE SS
  2178.                MOV   SAVE_SP,SP   ; SAVE SP
  2179.                MOV   AL,OPN_CODE
  2180.                CMP   AL,OP_D
  2181.                JNE    FAST_ND
  2182.                CALL   FASTBITS_D
  2183.                RET
  2184. FAST_ND:
  2185.                CMP   AL,OP_ND
  2186.                JNE    FAST_1
  2187.                CALL   FASTBITS_ND
  2188.                RET
  2189. FAST_1:
  2190.                CMP   AL,OP_ONES
  2191.                CALL   FASTBITS_1
  2192.                RET
  2193.                CALL   FASTBITS_0
  2194.                RET
  2195.                .XLIST
  2196.                SUBTTL    FAST COPY ROUTINE-----OPCODE OF D
  2197.                .LIST
  2198.                PAGE  +
  2199. ;
  2200. ;*********************************************************************
  2201. ;                                                                    *
  2202. ; COPY BITS FOR THE CASE OF  D  OPERATION CODE                       *
  2203. ;                                                                    *
  2204. ;*********************************************************************
  2205. ;
  2206. FASTBITS_D:
  2207.                MOV   SI,V_WORD_CNT
  2208.                STD                    ; FORWARD COPY, DET DIRECTION
  2209.                LES   DI,CURR_PTR_D
  2210.                CLI                  ; DISABLE INTERRUPTS
  2211.                MOV   BX,DSKEW_LEFT  ; GET PROLOGUE MASK
  2212.                CALL  GET_MASK
  2213.                MOV   DX,AX
  2214.                MOV   BX,DSKEW_RIGHT ; GET EPILOGUE MASK
  2215.                CALL  GET_BMASK
  2216.                MOV   SP,NWORDS
  2217.                MOV   SS,AX
  2218.                PAGE
  2219. D_VERT:
  2220.                XOR   BX,BX
  2221.                MOV   BL,HTONE_INDX   ; GET THE HALFTONE WORD
  2222.                AND   BL,HTONE_MOD    ; FOR THIS SCAN LINE
  2223.                MOV   BP,HTONE_VEC[BX]
  2224.                INC   BX
  2225.                MOV   HTONE_INDX,BL
  2226.                MOV   CX,SP           ; HORZ COUNT
  2227.                PAGE
  2228. ;*********************************************************************
  2229. ;                                                                    *
  2230. ;    FAST HORIZONTAL COPY ROUTINE                                    *
  2231. ;                                                                    *
  2232. ;                                                                    *
  2233. ;             ES,DI==>DEST    BITMAP                                 *
  2234. ;              BP = HALFTONE MASK                                    *
  2235. ;              DX = PROLOGUE MASK                                    *
  2236. ;              SS = EPILOGUE MASK                                    *
  2237. ;              SP = HORZ COUNT                                       *
  2238. ;                                                                    *
  2239. ;                                                                    *
  2240. ;*********************************************************************
  2241. ;
  2242. ;
  2243. ; PROLOGUE OPERATION
  2244. ;
  2245.                MOV   AX,ES:[DI]   ; GET SOURCE 1ST WORD
  2246.                MOV   BX,AX
  2247.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2248.                NOT   DX           ; MASK OFF STUFF TO KEEP
  2249.                AND   BX,DX
  2250.                AND   AX,BP        ; PUT IN HALF TONE
  2251.                OR    AX,BX        ; MERGE BACK
  2252.                MOV   ES:[DI],AX   ; PUT RESULT TO DESTINATION
  2253.                INC   DI
  2254.                INC   DI
  2255. D_INNER:
  2256.                AND   ES:[DI],BP      ; AND IN HALFTONE
  2257.                INC   DI
  2258.                INC   DI
  2259.                LOOP    D_INNER
  2260. ;
  2261. ; EPILOG OPERATION
  2262. ;
  2263.                MOV   AX,ES;[DI]   ; GET DEST LAST WORD
  2264.                MOV   DX,SS        ; EPILOGUE MASK IN SS
  2265.                MOV   BX,AX        ; BX WILL HAVE PART TO RETAIN
  2266.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2267.                NOT   DX
  2268.                AND   BX,DX
  2269.                AND   AX,BP        ; PUT IN HALF TONE
  2270.                OR    AX,BX        ; MERGE TOGETHER
  2271.                MOV   ES:[DI],AX
  2272.                INC   DI
  2273.                INC   DI
  2274.                PAGE
  2275. ;
  2276. ; LOWER PORTION OF VERT LOOP
  2277. ;
  2278.                ADD   DI,DELTA_D
  2279.                DEC   SI           ; ANOTHER H SCAN
  2280.                JNZ    D_VERT
  2281. ;
  2282.                MOV   SS,SAVE_SS
  2283.                MOV   SP,SAVE_SP
  2284.                STI                ; ENABLE INTERRUPTS
  2285.                RET
  2286.                .XLIST
  2287.                SUBTTL    FAST COPY ROUTINE-----OPCODE OF ~D
  2288.                .LIST
  2289.                PAGE  +
  2290. ;
  2291. ;*********************************************************************
  2292. ;                                                                    *
  2293. ; COPY BITS FOR THE CASE OF ~D  OPERATION CODE                       *
  2294. ;                                                                    *
  2295. ;*********************************************************************
  2296. ;
  2297. FASTBITS_ND:
  2298.                MOV   SI,V_WORD_CNT   ; STORE THE NUMBER OF LINES TO
  2299.                STD                    ; FORWARD COPY, DET DIRECTION
  2300.                LES   DI,CURR_PTR_D
  2301.                CLI                  ; DISABLE INTERRUPTS
  2302.                XOR   BH,BH
  2303.                MOV   BX,DSKEW_LEFT  ; GET PROLOGUE MASK
  2304.                CALL  GET_MASK
  2305.                MOV   DX,AX
  2306.                MOV   BX,DSKEW_RIGHT ; GET EPILOGUE MASK
  2307.                CALL  GET_BMASK
  2308.                MOV   SP,NWORDS
  2309.                MOV   SS,AX
  2310.                PAGE
  2311. ND_VERT:
  2312.                XOR   BX,BX
  2313.                MOV   BL,HTONE_INDX   ; GET THE HALFTONE WORD
  2314.                AND   BL,HTONE_MOD    ; FOR THIS SCAN LINE
  2315.                MOV   BP,HTONE_VEC[BX]
  2316.                INC   BX
  2317.                MOV   HTONE_INDX,BL
  2318.                MOV   CX,SP           ; HORZ COUNT
  2319.                PAGE
  2320. ;*********************************************************************
  2321. ;                                                                    *
  2322. ;    FAST HORIZONTAL COPY ROUTINE                                    *
  2323. ;                                                                    *
  2324. ;                                                                    *
  2325. ;             ES,DI==>DEST    BITMAP                                 *
  2326. ;              BP = HALFTONE MASK                                    *
  2327. ;              DX = PROLOGUE MASK                                    *
  2328. ;              SS = EPILOGUE MASK                                    *
  2329. ;              SP = HORZ COUNT                                       *
  2330. ;              SI = VERT COUNT                                       *
  2331. ;                                                                    *
  2332. ;*********************************************************************
  2333. ;
  2334. ;
  2335. ; PROLOGUE OPERATION
  2336. ;
  2337.                MOV   AX,ES:[DI]   ; GET SOURCE 1ST WORD
  2338.                MOV   BX,AX
  2339.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2340.                NOT   DX           ; MASK OFF STUFF TO KEEP
  2341.                AND   BX,DX
  2342.                NOT   AX
  2343.                AND   AX,BP        ; PUT IN HALF TONE
  2344.                OR    AX,BX        ; MERGE BACK
  2345.                MOV   ES:[DI],AX   ; PUT RESULT TO DESTINATION
  2346.                INC   DI
  2347.                INC   DI
  2348. ND_INNER:
  2349.                MOV   AX,ES:[DI]   ; GET DEST WORD
  2350.                NOT   AX
  2351.                AND   AX,BP
  2352.                MOV   ES:[DI],AX   ; STORE DEST WORD
  2353.                INC   DI
  2354.                INC   DI
  2355.                LOOP    ND_INNER
  2356. ;
  2357. ; EPILOG OPERATION
  2358. ;
  2359.                MOV   AX,ES;[DI]   ; GET DEST LAST WORD
  2360.                MOV   DX,SS        ; EPILOGUE MASK IN SS
  2361.                MOV   BX,AX        ; BX WILL HAVE PART TO RETAIN
  2362.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2363.                NOT   DX
  2364.                AND   BX,DX
  2365.                NOT   AX
  2366.                AND   AX,BP        ; PUT IN HALF TONE
  2367.                OR    AX,BX        ; MERGE TOGETHER
  2368.                MOV   ES:[DI],AX
  2369.                INC   DI
  2370.                INC   DI
  2371.                PAGE
  2372. ;
  2373. ; LOWER PORTION OF VERT LOOP
  2374. ;
  2375.                ADD   DI,DELTA_D
  2376.                DEC   SI           ; ANOTHER H SCAN
  2377.                JNZ    ND_VERT
  2378. ;
  2379.                MOV   SS,SAVE_SS
  2380.                MOV   SP,SAVE_SP
  2381.                STI                ; ENABLE INTERRUPTS
  2382.                RET
  2383.                .XLIST
  2384.                SUBTTL    FAST COPY ROUTINE-----OPCODE OF ALLONES
  2385.                .LIST
  2386.                PAGE  +
  2387. ;
  2388. ;*********************************************************************
  2389. ;                                                                    *
  2390. ; COPY BITS FOR THE CASE OF ONES AND ZEROES OPCODE                   *
  2391. ;                                                                    *
  2392. ;*********************************************************************
  2393. ;
  2394. FASTBITS_1:
  2395.                MOV   SI,V_WORD_CNT   ; STORE THE NUMBER OF LINES TO
  2396.                LES   DI,CURR_PTR_D
  2397.                CLI                  ; DISABLE INTERRUPTS
  2398.                XOR   BX,BX
  2399.                MOV   BX,DSKEW_LEFT  ; GET PROLOGUE MASK
  2400.                CALL  GET_MASK
  2401.                MOV   DX,AX
  2402.                MOV   BX,DSKEW_RIGHT ; GET EPILOGUE MASK
  2403.                CALL  GET_BMASK
  2404.                MOV   SS,AX
  2405.                MOV   SP,NWORDS
  2406.                PAGE
  2407. VERT_1:
  2408.                XOR   BX,BX
  2409.                MOV   BL,HTONE_INDX   ; GET THE HALFTONE WORD
  2410.                AND   BL,HTONE_MOD    ; FOR THIS SCAN LINE
  2411.                MOV   BP,HTONE_VEC[BX]
  2412.                INC   BX
  2413.                MOV   HTONE_INDX,BL
  2414.                MOV   CX,SP           ; HORZ COUNT
  2415.                PAGE
  2416. ;*********************************************************************
  2417. ;                                                                    *
  2418. ;    FAST HORIZONTAL COPY ROUTINE                                    *
  2419. ;                                                                    *
  2420. ;                                                                    *
  2421. ;             ES,DI==>DEST    BITMAP                                 *
  2422. ;              BP = HALFTONE MASK                                    *
  2423. ;              DX = PROLOGUE MASK                                    *
  2424. ;              SS = EPILOGUE MASK                                    *
  2425. ;              SP = HORZ COUNT                                       *
  2426. ;              SI = VERT COUNT                                       *
  2427. ;                                                                    *
  2428. ;*********************************************************************
  2429. ;
  2430. ;
  2431. ; PROLOGUE OPERATION
  2432. ;
  2433.                MOV   AX,ES:[DI]   ; GET SOURCE 1ST WORD
  2434.                MOV   BX,AX
  2435.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2436.                NOT   DX           ; MASK OFF STUFF TO KEEP
  2437.                AND   BX,DX
  2438.                AND   AX,BP        ; PUT IN HALF TONE
  2439.                OR    AX,BX        ; MERGE BACK
  2440.                MOV   ES:[DI],AX   ; PUT RESULT TO DESTINATION
  2441.                INC   DI
  2442.                INC   DI
  2443. INNER_1:
  2444.                AND   ES:[DI],BP   ; BP ANREADY AND'D WITH 0'S/1'S
  2445.                INC   DI
  2446.                INC   DI
  2447.                LOOP    INNER_1
  2448. ;
  2449. ; EPILOG OPERATION
  2450. ;
  2451.                MOV   AX,ES:[DI]   ; GET DEST LAST WORD
  2452.                MOV   DX,SS        ; EPILOGUE MASK IN SS
  2453.                MOV   BX,AX        ; BX WILL HAVE PART TO RETAIN
  2454.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2455.                NOT   DX
  2456.                AND   BX,DX
  2457.                AND   AX,BP        ; PUT IN HALF TONE
  2458.                OR    AX,BX        ; MERGE TOGETHER
  2459.                MOV   ES:[DI],AX
  2460.                INC   DI
  2461.                INC   DI
  2462.                PAGE
  2463. ;
  2464. ; LOWER PORTION OF VERT LOOP
  2465. ;
  2466.                ADD   DI,DELTA_D
  2467.                DEC   SI           ; ANOTHER H SCAN
  2468.                JNZ    VERT_1
  2469. ;
  2470.                MOV   SS,SAVE_SS
  2471.                MOV   SP,SAVE_SP
  2472.                STI                ; ENABLE INTERRUPTS
  2473.                RET
  2474.                .XLIST
  2475.                SUBTTL    FAST COPY ROUTINE-----OPCODE OF ALLZEROES
  2476.                .LIST
  2477.                PAGE  +
  2478. ;
  2479. ;*********************************************************************
  2480. ;                                                                    *
  2481. ; COPY BITS FOR THE CASE OF ONES AND ZEROES OPCODE                   *
  2482. ;                                                                    *
  2483. ;*********************************************************************
  2484. ;
  2485. FASTBITS_0:
  2486.                MOV   SI,V_WORD_CNT   ; STORE THE NUMBER OF LINES TO
  2487.                LES   DI,CURR_PTR_D
  2488.                CLI                  ; DISABLE INTERRUPTS
  2489.                XOR   BX,BX
  2490.                MOV   BX,DSKEW_LEFT  ; GET PROLOGUE MASK
  2491.                CALL  GET_MASK
  2492.                MOV   DX,AX
  2493.                MOV   BX,DSKEW_RIGHT ; GET EPILOGUE MASK
  2494.                CALL  GET_BMASK
  2495.                MOV   SS,AX
  2496.                MOV   SP,NWORDS
  2497.                XOR   BP,BP          ; CLEAR DESTINATION
  2498. VERT_0:
  2499.                MOV   CX,SP           ; HORZ COUNT
  2500.                PAGE
  2501. ;*********************************************************************
  2502. ;                                                                    *
  2503. ;    FAST HORIZONTAL COPY ROUTINE                                    *
  2504. ;                                                                    *
  2505. ;                                                                    *
  2506. ;             ES,DI==>DEST    BITMAP                                 *
  2507. ;              BP = HALFTONE MASK                                    *
  2508. ;              DX = PROLOGUE MASK                                    *
  2509. ;              SS = EPILOGUE MASK                                    *
  2510. ;              SP = HORZ COUNT                                       *
  2511. ;              SI = VERT COUNT                                       *
  2512. ;                                                                    *
  2513. ;*********************************************************************
  2514. ;
  2515. ;
  2516. ; PROLOGUE OPERATION
  2517. ;
  2518.                MOV   AX,ES:[DI]   ; GET SOURCE 1ST WORD
  2519.                MOV   BX,AX
  2520.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2521.                NOT   DX           ; MASK OFF STUFF TO KEEP
  2522.                AND   BX,DX
  2523.                AND   AX,BP        ; PUT IN HALF TONE
  2524.                OR    AX,BX        ; MERGE BACK
  2525.                MOV   ES:[DI],AX   ; PUT RESULT TO DESTINATION
  2526.                INC   DI
  2527.                INC   DI
  2528. INNER_0:
  2529.                AND   ES:[DI],BP   ; BP ANREADY AND'D WITH 0'S/1'S
  2530.                INC   DI
  2531.                INC   DI
  2532.                LOOP    INNER_0
  2533. ;
  2534. ; EPILOG OPERATION
  2535. ;
  2536.                MOV   AX,ES:[DI]   ; GET DEST LAST WORD
  2537.                MOV   DX,SS        ; EPILOGUE MASK IN SS
  2538.                MOV   BX,AX        ; BX WILL HAVE PART TO RETAIN
  2539.                AND   AX,DX        ; MASK OFF 1ST WORD DATA TO KEEP
  2540.                NOT   DX
  2541.                AND   BX,DX
  2542.                AND   AX,BP        ; PUT IN HALF TONE
  2543.                OR    AX,BX        ; MERGE TOGETHER
  2544.                MOV   ES:[DI],AX
  2545.                INC   DI
  2546.                INC   DI
  2547.                PAGE
  2548. ;
  2549. ; LOWER PORTION OF VERT LOOP
  2550. ;
  2551.                ADD   DI,DELTA_D
  2552.                DEC   SI           ; ANOTHER H SCAN
  2553.                JNZ    VERT_0
  2554. ;
  2555.                MOV   SS,SAVE_SS
  2556.                MOV   SP,SAVE_SP
  2557.                STI                ; ENABLE INTERRUPTS
  2558.                RET
  2559. COPY_FAST      ENDP
  2560.                .XLIST
  2561.                SUBTTL    CALCULATE SCAN LINES PROCESSED IN 1/60 SEC
  2562.                .LIST
  2563.                PAGE  +
  2564.                PAGE  +
  2565. HTONE_GET      PROC  NEAR
  2566. HTONE_GET      ENDP
  2567. COPY_DISPLAY   PROC  NEAR
  2568. COPY_DISPLAY   ENDP
  2569. BITBLT_INIT    PROC  NEAR
  2570. BITBLT_INIT    ENDP
  2571. BITBLT         ENDP
  2572. ?BITBLT        ENDS
  2573.                END
  2574.